全局变量的值变化不会立即更新?

Posted

技术标签:

【中文标题】全局变量的值变化不会立即更新?【英文标题】:Change in the values of global variables not immediately updated? 【发布时间】:2016-01-17 04:44:49 【问题描述】:

在以下代码中,我尝试在函数test() 中修改所有全局变量(stuv)。因为uv 在模块内,Mod.uMod.v 是只读变量,所以我尝试通过setter 函数(set_uset_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 只修复了变量的类型)。但我不明白为什么tMod.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 全局类型可能对我的目的有用......但我也会尝试考虑更多“朱利安”方式来存储参数,而不是简单地从其他语言翻译。谢谢:)

以上是关于全局变量的值变化不会立即更新?的主要内容,如果未能解决你的问题,请参考以下文章

全局变量更新 AJAX POST

QT/C++外部变量或者全局变量怎么使用,来个能说清楚的。

为啥存储函数总是引用更新后的全局 i 变量的值?

局部函数和全局函数

C: 为啥我的库中的全局变量不会更新? (使用 ALSA 库)

全局变量不会在C中的线程更新[关闭]