global-variables - 为什么我可以更改另一个模块中的数组的值,但不能更改变量的值

标签 global-variables julia

我有一个模块,我想将其用作一组全局变量。

文件Global.jl:

module Global

    export data
    export dataLoaded

    data = zeros(Int32, 20, 12, 31, 24, 60, 5);

    dataLoaded = false;

end

文件ma​​in2.jl:

include("Global.jl")
import .Global


println(Global.data[10,1,1,1,1,1])
println(Global.dataLoaded)

Global.data[10,1,1,1,1,1] = 5
println(Global.data[10,1,1,1,1,1])

Global.dataLoaded = true
println(Global.dataLoaded)

我没想到 dataLoaded 不能像 data 那样进行更改。有没有办法允许更改dataLoaded

$ /usr/local/julia-1.2.0/bin/julia main2.jl
0
false
5
ERROR: LoadError: cannot assign variables in other modules
Stacktrace:
 [1] setproperty!(::Module, ::Symbol, ::Bool) at ./Base.jl:14
 [2] top-level scope at /usr/home/.../main2.jl:11
 [3] include at ./boot.jl:328 [inlined]
 [4] include_relative(::Module, ::String) at ./loading.jl:1094
 [5] include(::Module, ::String) at ./Base.jl:31
 [6] exec_options(::Base.JLOptions) at ./client.jl:295
 [7] _start() at ./client.jl:464
in expression starting at /usr/home/.../main2.jl:11

最佳答案

正如我在 How to define global variables to be shared later in Julia 中评论的那样不允许您从模块外部更改变量的绑定(bind)。

首先,解释一下正在发生的事情:

x = [1,2,3]
x[1] = 10

第二个操作x[1] = 10不会更改x的绑定(bind),它仅更改存储在向量x的第一个元素中的值(因为向量是可变的)。

另一方面写:

y = 1
y = 10

首先将 y 定义为值 1(Int 类型,不可变),然后 y = 10 重新绑定(bind) y 以保持 10

现在 - 如何解决您的问题。有两种方法:

第一个是在 Global 模块中定义一个 setter 函数,如下所示:

function setdataloaded(value::Bool)
    global dataLoaded = value
end

由于 setdataloaded 是在 Global 模块中定义的,因此它可以更改该模块中变量的绑定(bind)。然后您可以从模块外部调用setdataloaded来更改dataLoaded的值。

第二个是使用可变容器而不是不可变容器。最简单的是Ref。所以你可以定义:

dataLoaded = Ref(false)

然后您可以获得 dataLoaded[] 的值,并从 Global 外部设置其值,例如 dataLoaded[] = true模块(因为这次您要改变容器的内容,而不是重新绑定(bind) dataLoaded)。

编辑

正如评论中所指出的,从技术上讲,您可以在 Global 模块内评估 dataLoaded = 10 表达式,甚至可以从该模块外部的代码中编写:

@eval Global dataLoaded = 10

Global.eval(:(dataLoaded = 10))

事实上,每个模块(baremodule 除外,但这是一种罕见的用例)都有自己的 eval 模块本地定义。

在某种程度上,eval 方法是我描述的第一种方法(使用 setter 函数),默认情况下是允许的。

关于global-variables - 为什么我可以更改另一个模块中的数组的值,但不能更改变量的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57939498/

相关文章:

python - 为什么访问全局变量不需要 'global' 关键字?

c++ - 静态和全局变量存储说明

c++ - 在游戏编程中,全局变量不好吗?

dataframe - 在 Julia 中将 DataFrame 重新采样为每小时 15 分钟和 5 分钟

types - 在 Julia 中构造具有相关字段的类型

c++ - 在另一个文件中使用另一个类的变量

c++更改不同文件中的全局变量值

julia - 测试 Julia 包时如何包含位于 test 文件夹之外的文件

arguments - Julia:如何使用关键字参数?

matlab - Julia 中 "parfor"类型循环的实现