繁体   English   中英

Ruby循环局部变量和不变性

[英]Ruby loop local variables and inmutability

我有以下代码:

# Assuming each element in foo is an array.
foo.each do |bar|
  zaz = bar.first
  # Other code using zaz, but not modifying it.
end

是否会在此循环内的每次迭代中修改zaz局部变量,使其可变? 我不确定Ruby的行为。

实际上,这取决于循环之前的代码。

如果这就是全部代码,则zaz是块局部变量,并且每次评估循环体时都将创建一个新的 zaz变量。

但是,如果周围范围中有zaz局部变量,则zaz是块中的自由变量,并且由于块范围嵌套在其周围范围中,因此,将zaz重新分配该块外部的现有zaz变量再次,每次评估块。

通过在块的参数列表中明确将其声明为块局部变量,可以确保zaz始终被视为块局部变量,并且永远不会在周围的范围中查找:

foo.each do |bar; zaz|
  zaz = bar.first
end

但是请注意,你的代码才有意义IFF你的代码是不纯的和可变的:

  1. 您分配给zaz但从未在块内实际使用它。 因此,这唯一有意义的唯一方法是zaz是外部作用域中的局部变量,并且您正在分配它。 尽管在这种情况下,您的整个循环仅等效于zaz = foo.last.first
  2. each仅评估其副作用。 没有副作用, each副作用就完全没有意义,因此您正在使用each副作用这一事实意味着您有副作用。

注意,没有附加限定的术语“不变”通常是指值。 在谈论“不可变变量”时,我们通常会明确地说“不可变变量”,以表明我们只是在谈论变量是否可以重新绑定,而不是在改变对象状态。 或者,可以只说“常量”,这是“不可变变量”的技术术语……尽管该术语在Ruby中已经具有特定的含义。

each循环通常会使对象变异。 每个人都必须做某事。 因为each元素都不会返回任何有用的信息-它会返回数组本身,所以如果将每个元素发送到某个地方(例如在屏幕上打印),它都不会使对象发生变异。

foo.each do |bar|
  # do something with element like
  # print it, change it, save it
end

功能替代图

foo.map { |bar| bar.something }

它返回新数组,这是以不变方式处理的原始数组。 显然,您必须小心使用不可变的方法。 这不是一成不变的:

foo.map { |bar| bar.something! } 

在这里something! 对数组元素有破坏性。 但是我从未见过像那样使用过的map 使用each破坏性的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM