全局变量的值变化不会立即更新?
Posted
技术标签:
【中文标题】全局变量的值变化不会立即更新?【英文标题】:Change in the values of global variables not immediately updated? 【发布时间】:2016-01-17 04:44:49 【问题描述】:在以下代码中,我尝试在函数test()
中修改所有全局变量(s
、t
、u
、v
)。因为u
和v
在模块内,Mod.u
和Mod.v
是只读变量,所以我尝试通过setter 函数(set_u
和set_v
)更改它们的值。
s = 1
const t = 2
module Mod
u = 3
const v = 4
set_u( u_ ) = ( global u ; u = u_ )
set_v( v_ ) = ( global v ; v = v_ )
end
function test()
global s, t
s = "S" ; t = 200
@show s, t
Mod.set_u( "U" ) ; Mod.set_v( 400 )
@show Mod.u, Mod.v
end
test()
@show s, t
@show Mod.u, Mod.v
结果(使用 Julia v0.4.0 获得)是
WARNING: redefining constant t
(s,t) = ("S",2) # (1)
WARNING: redefining constant v
(Mod.u,Mod.v) = ("U",4) # (2)
(s,t) = ("S",200) # (3)
(Mod.u,Mod.v) = ("U",400) # (4)
这里,(3) 和 (4) 是我的预期结果(假设 const
只修复了变量的类型)。但我不明白为什么t
和Mod.v
的值没有在(1)和(2)中更新。我是否在更改全局变量的值方面犯了一些大错误或误解......?还是因为从函数内部或外部引用全局变量的机制不同?
【问题讨论】:
【参考方案1】:唯一没有在函数体中“更新”的常量是那些你标记为const
的常量。
(假设
const
只修复了变量的类型)
这个假设是不正确的。虽然 Julia 确实允许您更改 const
绑定的值,但重新定义 const
变量肯定会导致问题。请注意,它警告您这不是一个好主意。
这里有一个简单的例子来说明正在发生的事情:
julia> const t = 3
f() = t
f (generic function with 1 method)
julia> @code_llvm f()
define i64 @julia_f_21636()
top:
ret i64 3
julia> t = 4
@code_llvm f()
WARNING: redefining constant t
define i64 @julia_f_21636()
top:
ret i64 3
您无需非常精通阅读 LLVM IR 即可看到它返回整数 3 并且不进行查找。它看到t
被标记为常量,并在编译函数时使用该信息对其进行优化。打破const
并更改t
的值不会导致重新编译f
,因此会返回旧值。 LLVM 对于非常量全局来说更复杂,但它仍然非常易读。你可以看到它正在从某个地方加载一个值:
julia> s = 2
g() = s
@code_llvm g()
define %jl_value_t* @julia_g_21649()
top:
%0 = load %jl_value_t** inttoptr (i64 4417498392 to %jl_value_t**), align 8
ret %jl_value_t* %0
简而言之:如果你对变量的 const
-ness 撒谎,当 Julia 给你一个旧答案时,你不应该感到惊讶。
【讨论】:
啊,好吧,现在我明白了...我一直假设const
只修复变量的类型(因为它允许更改值),但这似乎很危险,因为代码编译利用假定的 constness... 我试图在 Julia 模块中使用 const 全局变量作为模拟中的“可修改参数”(遵循 Fortran 模块中的流行方式),但这似乎不是一个好主意。非常感谢:)
刚刚使用 const t=[3]
作为 LLVM 优化的实用解决方法进行了测试。类型信息被保留:typeof(t[1])==Int64
并且可以更改内容。同样,这是一种变通方法,但它确实有效。
@user3580870 您好,我刚刚还确认您的方法有效。此外,似乎可以对 const 全局复合类型使用相同的技巧(即 Any 在其字段仍然可变时不会传播)。所以这种 const 全局类型可能对我的目的有用......但我也会尝试考虑更多“朱利安”方式来存储参数,而不是简单地从其他语言翻译。谢谢:)以上是关于全局变量的值变化不会立即更新?的主要内容,如果未能解决你的问题,请参考以下文章