本文介绍了为什么在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关键字的限定,如 shadowtalker所解释的);
  • 局部作用域从封闭的局部作用域继承变量以进行读写,除非它们用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之前,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中循环中的此分配失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 03:56