为什么Julia代码逐行运行正常,全部运行时却报UndefVarError错误
问题成因说明
这个差异本质是Julia 1.6版本的作用域规则和Juno两种运行模式的作用域处理逻辑不同导致的:
- 首先明确Julia 1.0到1.6版本的soft scope默认规则:
当代码在非交互的脚本模式下运行时,for循环、while循环这类块会创建局部作用域。如果在块内对一个已经存在的全局变量做赋值操作,Julia会默认将这个变量识别为全新的局部变量,而不是修改上层的全局变量。你代码里的gamma在全局定义,for循环内写gamma = gamma + 1.e0/j的时候,右侧要读取gamma的值,但此时Julia已经把这个gamma标记为未初始化的局部变量,所以会抛出UndefVarError。 - 两种运行方式的逻辑差异:
- 逐行按Ctrl+Enter运行时,Juno是将每一行代码送到交互式REPL环境执行,Julia的REPL对soft scope做了特殊适配:顶层块内的赋值会默认修改全局变量,不会强制创建新的局部变量,所以运行不会报错。
- 按Ctrl+Shift+Enter全量运行时,Juno是将整个代码作为独立脚本交给Julia执行,严格遵循脚本模式的默认作用域规则,没有REPL的适配逻辑,因此触发了警告和报错。
如果要修复这个问题,可以选择以下任意一种方案:
- 在for循环内部第一行加上
global gamma,明确指定要修改全局作用域的gamma变量 - 将所有逻辑封装到函数内部,函数的局部作用域规则不存在该歧义
- 升级Julia到1.7及以上版本,该版本调整了顶层作用域规则,脚本模式和REPL模式的作用域处理逻辑已经统一,不会再出现该错误。
内容的提问来源于stack exchange,提问作者Idiot
相关产品推荐
相关产品推荐

