Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 块中局部变量的作用域_Ruby_Block_Variable Assignment - Fatal编程技术网

Ruby 块中局部变量的作用域

Ruby 块中局部变量的作用域,ruby,block,variable-assignment,Ruby,Block,Variable Assignment,如果我有: 2.times do i ||= 1 print "#{i} " i += 1 print "#{i} " end 我得到了1212,而我期望的是1233。循环重新开始时,i为什么会丢失其赋值?如果赋值发生在循环之外,它的行为与预期的一样,因此我猜这与作用域有关,但我没有意识到循环有自己的作用域。有人能澄清一下吗 更新:谢谢你在这方面的帮助。我的一部分困惑源于从Python到Ruby,它没有块作用域(我想) 没有范围的不是“循环”。这是街区。是的,块是局部范围 如果

如果我有:

2.times do
  i ||= 1
  print "#{i} "
  i += 1
  print "#{i} "
end
我得到了
1212
,而我期望的是
1233
。循环重新开始时,
i
为什么会丢失其赋值?如果赋值发生在循环之外,它的行为与预期的一样,因此我猜这与作用域有关,但我没有意识到循环有自己的作用域。有人能澄清一下吗

更新:谢谢你在这方面的帮助。我的一部分困惑源于从Python到Ruby,它没有块作用域(我想)

没有范围的不是“循环”。这是街区。是的,块是局部范围

如果不希望将变量理解为块的局部变量,则它需要预先存在于块之外。即使只是在前一行中将
i
设置为nil也可以做到这一点


(但是你对
1234
的期望还没有完全实现…!)

我不知道你的期望是基于什么。如果你像我想的那样思考,那应该是
123code>。您可以通过在块外部声明变量
i
来实现这一点

i = nil

2.times do
  i ||= 1
  print "#{i} "
  i += 1
  print "#{i} "
end
block = -> do
  x = "Hello from inside a block"
  binding # return the binding
end

p defined? x              #=> nil
x = eval "x", block.call  #=> #<Binding:0x007fce799c7dc8>
p defined? x              #=> "local-variable"
p x                       #=> "Hello from inside a block"

然后块关闭该变量(闭包)并使用它。没有闭包,
i
是块的本地代码,每次都是新代码。

查看下面的代码:

2.times do
  p defined? i
  i ||= 1
  p defined? i
  p "#{i} "
  i += 1
  p "#{i} "
end
输出:

nil 
"local-variable"
"1 "
"2 "
nil
"local-variable"
"1 "
"2 "
这意味着在每次迭代中都会创建一个新的范围,并且
i
仅对该范围是已知的;这是由
nil
局部变量
证明的

现在
i
块的外部创建,并查看输出(no
nil
来了):

输出:


要了解更多关于
| |=
的信息,请查看您可以从中获得一些乐趣。例如,假设您希望访问块内的作用域

i = nil

2.times do
  i ||= 1
  print "#{i} "
  i += 1
  print "#{i} "
end
block = -> do
  x = "Hello from inside a block"
  binding # return the binding
end

p defined? x              #=> nil
x = eval "x", block.call  #=> #<Binding:0x007fce799c7dc8>
p defined? x              #=> "local-variable"
p x                       #=> "Hello from inside a block"
block=->do
x=“你好,从一个街区内”
绑定#返回绑定
结束
p定义了什么?x#=>零
x=评估“x”,block.call#=>#
p定义了什么?x#=>“局部变量”
Px#=>“街区内的你好”

这一点很重要,因为它允许开发人员基本上消除块的封装,应该谨慎使用。

简单的答案是,在每次迭代中重新关联变量
i
,并将其重置为1的值。

Ruby循环类似于
x.times
创建局部范围,因此在该循环中引入的变量是局部的,在到达块末尾后将被销毁。这就是为什么你没有得到预期的结果。 在ruby中,如果希望循环不包含局部作用域,可以使用
for
,而
循环不创建局部作用域,但局部变量
i
将在循环后保持可访问性

for j in (1..2)
  i ||= 1
  print "#{i} "
  i += 1
  print "#{i} "
end

按预期结果打印
1 2 3
。现在,如果我们在循环老化上面运行,它将给出结果
3 4 5
。对于额外的信息,
对于
的工作方式相同(无范围&打印
1 2 3
),另一方面,
每个
x.upto(y)
x.times
工作方式相同(创建本地范围并打印
1 2 1 2

这是出于教学目的吗?因为这类代码是完全不符合逻辑的……事实上,即使只是
如果为false,那么i=nil end
就足够了,但在这种情况下,确切的原因可能太令人困惑而无法解释。