为什么在 Julia 0.7 和 1.0 中循环内的这个赋值会失败? [英] Why does this assignment inside a loop fail in Julia 0.7 and 1.0?

查看:8
本文介绍了为什么在 Julia 0.7 和 1.0 中循环内的这个赋值会失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(k, a, b, a1, b1) = (BigInt(2), BigInt(4), BigInt(1), BigInt(12), BigInt(4))

while k <= BigInt(4)
  (p, q, k) = (k*k, BigInt(2)*k+BigInt(1), k+BigInt(1))
end

此代码在 Julia 0.6 中编译和运行,但在 1.0 中会产生 ERROR: UndefVarError: k not defined.

This code compiles and runs in Julia 0.6, but in 1.0 produces ERROR: UndefVarError: k not defined.

版本之间有什么变化吗?Julia 1.0 中的这段代码有什么问题?

Did something change between versions? What's wrong with this code in Julia 1.0?

推荐答案

shadowtalker的回答是正确的.然而,这段代码有一个重要问题值得添加更多解释(而且评论太长了).

The answer by shadowtalker is correct. However, there is one important issue with this code that is worth adding some more explanation (and it was too long for a comment).

Julia 中针对此案例的相关范围规则如下(如果您想阅读详细信息,可以在此处找到它们https://docs.julialang.org/en/latest/manual/variables-and-scoping/#Local-Scope-1):

The relevant scoping rules in Julia for this case are the following (and if you want to read the details you can find them here https://docs.julialang.org/en/latest/manual/variables-and-scoping/#Local-Scope-1):

  • while 块引入了一个新的局部作用域;
  • 本地范围从封闭的全局范围继承变量仅用于读取(除非它们使用 global 关键字限定,如 暗语者);
  • 本地作用域从封闭的本地作用域继承变量以进行读写,除非它们用 local 关键字限定.
  • while block introduces a new local scope;
  • local scope inherits variables from enclosing global scope only for reading (unless they are qualified with global keyword as explained by shadowtalker);
  • local scope inherits variables from enclosing local scope for reading and writing unless they are qualified with local keyword.

现在 - 为什么这很重要?原因是,如果您在全局范围内(例如在 Julia REPL 中)运行代码,您的代码的行为会有所不同,而如果您在本地范围内(例如在函数内部)运行,代码的行为会有所不同.

Now - why this is important? The reason is that your code will behave differently if you run it in global scope (e.g. in Julia REPL) and differently if you have it in a local scope (e.g. inside a function).

如果您在全局范围内运行它,则需要 shadowtalker 显示的内容.但是,如果你运行它,例如在函数内部,您不必更改任何内容.例如此函数将正常工作:

If you run it in global scope then what shadowtalker showed is needed. However, if yourun it e.g. inside a function you do not have to change anything. For example this function will work correctly:

function f()
    (k, a, b, a1, b1) = (BigInt(2), BigInt(4), BigInt(1), BigInt(12), BigInt(4))

    while k <= BigInt(4)
      (p, q, k) = (k*k, BigInt(2)*k+BigInt(1), k+BigInt(1))
    end
end

如果你也没有创建一个函数,例如在全局范围内使用 let 块,代码将按预期运行:

also without creating a function if you e.g. use let block in a global scope the code will just run as intended:

let
    k, a, b, a1, b1 = BigInt(2), BigInt(4), BigInt(1), BigInt(12), BigInt(4)

    while k <= BigInt(4)
      (p, q, k) = (k*k, BigInt(2)*k+BigInt(1), k+BigInt(1))
    end

    k, a, b, a1, b1
end

因为 let 创建了一个本地范围(我在 let 块的末尾添加了语句,以使其评估为引入变量的值,以便您可以检查他们).

because let creates a local scope (I have added the statement at the end of let block to make it evaluate to the values of the introduced variables so that you can inspect them).

与 Julia 0.6 及更早版本相比,这是一个重大变化,其中 Julia 区分了硬本地范围和软本地范围(请参阅此处 https://docs.julialang.org/en/release-0.6/manual/variables-and-scoping/#scope-of-variables-1),但是这种区别已经消失了——所有的局部作用域现在的行为都是一样的.这是一个重大的变化,实际上它意味着如果您将其复制粘贴到全局范围内,您可以期望在某个本地范围内正确运行的代码(大多数情况下是一个函数)将改变其行为.根据我使用 let 块的经验,如上所示是缓解此问题的最简单方法.

This is a significant change from Julia 0.6 and earlier where Julia made a difference between hard and soft local scopes (see here https://docs.julialang.org/en/release-0.6/manual/variables-and-scoping/#scope-of-variables-1), but this distinction is gone - all local scopes now behave identically. This is a significant change an in practice it means that you can expect that the code that runs correctly inside some local scope (a function in most cases) will change its behavior if you copy-paste it to a global scope. From my experience using let blocks as shown above is the simplest way alleviate this problem.

这篇关于为什么在 Julia 0.7 和 1.0 中循环内的这个赋值会失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆