如何不在 Julia 的内部块中隐藏变量?

Ale*_*hin 2 julia

下面的代码,查找价格差异不起作用。因为previous_price变量是阴影的。

prices = [1, 2, 3, 2, 4]
diffs, previous_price = [], prices[1]
for price in prices
  diff = round(price / previous_price; digits = 2)
  push!(diffs, diff)
  previous_price = price
end
Run Code Online (Sandbox Code Playgroud)

可能的解决方法是将其放入容器中,但也许有更好的方法

prices = [1, 2, 3, 2, 4]
diffs, previous_price = [], [prices[1]]
for price in prices
  diff = round(price / previous_price[1]; digits = 2)
  push!(diffs, diff)
  previous_price[1] = price
end
Run Code Online (Sandbox Code Playgroud)

Fen*_*ang 6

这是因为虽然局部作用域可以重新绑定父局部作用域的名称,但它们不能在没有显式注释的情况下重新绑定父全局作用域的名称global。相反,赋值语句x = <...>将创建一个新的本地绑定,这会导致您看到的错误。

因此,您的问题的几种可能解决方案包括:

使外部作用域成为局部作用域

这是我推荐的解决方案。一般来说,最好在局部作用域中工作,因为函数、循环等都在局部作用域中,您可能希望将代码从脚本转换为库,并在将来使其成为函数。创建本地作用域的最简单方法是使用let.

julia> let
         prices = [1, 2, 3, 2, 4]
         diffs, previous_price = [], prices[1]
         for price in prices
           diff = round(price / previous_price; digits = 2)
           push!(diffs, diff)
           previous_price = price
         end
         diffs
       end
5-element Array{Any,1}:
 1.0
 2.0
 1.5
 0.67
 2.0
Run Code Online (Sandbox Code Playgroud)

请注意,这很容易转换为一个函数,该函数将其prices作为参数并返回diffs!通常,此类解决方案是首选,因为它们最可重用。

使局部作用域指向全局作用域 prices

这不是推荐的解决方案,因为改变全局变量效率低下且组合不好(即,如果您想从多个地方多次调用此例程,也许在不同的线程中,它们可能会与同一个全局变量发生冲突previous_price!)

julia> prices = [1, 2, 3, 2, 4]
5-element Array{Int64,1}:
 1
 2
 3
 2
 4

julia> diffs, previous_price = [], prices[1]
(Any[], 1)

julia> for price in prices
         global previous_price
         diff = round(price / previous_price; digits = 2)
         push!(diffs, diff)
         previous_price = price
       end

julia> diffs
5-element Array{Any,1}:
 1.0
 2.0
 1.5
 0.67
 2.0
Run Code Online (Sandbox Code Playgroud)

请注意该global previous_price行的引入,它强制内部previous_price绑定成为全局绑定。

用一个 Ref

在大多数情况下也不推荐此解决方案,但我将其包括在内,因为它是您提出的解决方案,但具有更合适的容器类型。ARef有点像指针:它允许您更改它包含的对象,而无需重写绑定本身。这意味着,不再有任何分配到previous_pricefor环,因此,现在绑定到外部previous_price,在这种情况下是全球性的。该代码与您可能的解决方法相同,但它更有效,更清楚发生了什么。

prices = [1, 2, 3, 2, 4]
diffs, previous_price = [], Ref(prices[1])
for price in prices
  diff = round(price / previous_price[]; digits = 2)
  push!(diffs, diff)
  previous_price[] = price
end
Run Code Online (Sandbox Code Playgroud)

请注意,Refs 是用 访问的[],而不是[1]像您的单元素向量那样访问。