Julia中变量的作用域

15

当我运行下面的Julia代码时,出现了错误:UndefVarError: globalValue not defined

我本以为globalValue是一个全局变量,但实际上并不是。因此,如果我在for循环中添加“global globalValue”命令,我的代码就能正常工作。所以,有没有人能看一下并告诉我发生了什么?先谢谢了!

globalValue = 1.0;
tempValue   = 0.1;
for ii = 1:10
    # global globalValue; if I add this command, my code will work
    tempValue = 5.0; ## I have a function to update "tempValue"
    if globalValue < tempValue
        globalValue = tempValue;
    end
end

1
嗨@nhavt,我看到你在stackoverflow上还是新手。通常,如果一个答案解决了您的问题,请考虑通过单击复选框来接受它,这将向更广泛的社区表示您已经找到了解决方案,并且为回答者和您自己带来了一些声望。当然,这并非强制性要求。您也可以考虑接受其他问题的答案。 - carstenbauer
嗨@crstnbr,谢谢你的信息。我从现在开始一定会这样做! - nhavt
1个回答

23

看起来你正在使用 Julia >= 0.7,其中作用域规则已经发生了变化。

简而言之,在本地作用域(例如您的 for 循环)中,全局变量只能被继承到读取,但不能被继承到写入。有两种解决方法:

  • 在赋值前面放上显式的 global(就像你自己想出来的那样)
  • 将所有内容包装在“全局局部作用域”中,如 let ... end 块(globalValue 实际上不再是全局变量)

在您的情况下,第二个选项看起来像这样:

let
globalValue = 1.0;
tempValue   = 0.1;
for ii = 1:10
    tempValue = 5.0;## I have a function to update "tempValue"
    if globalValue < tempValue
        globalValue = tempValue;
    end
end
end

你可以在这里找到更多信息: 尽管我自己也觉得这有点烦人,但改变已经做出来了,而且有很好的理由。此外,应该尽量避免更改全局变量。让我在这里引用手册(参见上面的链接):

许多人认为避免更改全局变量的值是一种最佳编程实践。其中一个原因是,在其他模块中远程更改全局变量的状态应该谨慎进行,因为它使程序的本地行为难以理解。这就是为什么引入本地作用域的作用域块需要使用global关键字声明修改全局变量的意图。


感谢您查看此问题并进行解释。确实,我目前正在使用Julia 1.0,其中变量的作用域规则已经发生了变化。而我并不知道这一点。然而,似乎第二个选项目前无法工作。也许,我将详细查看参考资料,看看发生了什么。非常感谢您的帮助! - nhavt
再看一遍,现在它可以工作了。原来全局变量的名称是 globalValue,而你在循环中尝试更新 globalOptiValue。你也可以在你的问题中更改这个。 - carstenbauer
是的,确实是我的笔误。现在它完美地工作了。非常感谢你的帮助! - nhavt
很高兴能够帮助到您。 - carstenbauer
2
许多人将被重定向到这里,所以我想添加我的发现。您可以在全局定义的循环内写入变量,并创建一个单独的本地版本。只有当您尝试在同一循环中读取和写入全局变量时(例如i=i+1),Julia 才会抱怨。这是因为 Julia 不知道您想要全局还是本地版本,除非声明为这样。因此,在循环中单独陈述 println(globalValue)globalValue=2 可以没有错误,但不能同时使用。当我自己测试范围时,这些微妙之处令人困惑。 - Nathan Boyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接