在David Black的The Well-Grounded Rubyist中,我遇到了以下关于枚举器的Ruby代码:
e = Enumerator.new do |y|
puts "Starting up the block!"
(1..3).each {|i| y << i }
puts "Exiting the block!"
end
p e.to_a
返回以下输出:
Starting up the block!
Exiting the block!
[1, 2, 3]
最让我困扰的是,我无法围绕执行的顺序。我相信输出应该更直接:
Starting up the block!
[1, 2, 3]
Exiting the block!
非常感谢任何帮助。
答案 0 :(得分:4)
如果要从Enumerator中创建一个数组,必须首先从中提取每个元素!
Ruby需要确保不遗漏任何内容,并且需要在返回数组之前执行整个Block。可能有另一行定义了更多元素:
Starting up the block!
Exiting the block! (Not really)
Exiting the block!
[1, 2, 3, 4, 5, 6]
输出:
p e.next
p e.next
p e.next
p e.next
作为替代方案,您可以使用:
Starting up the block!
1
2
3
Exiting the block!
enum.rb:11:in `next': iteration reached an end (StopIteration)
输出:
e.each do |x|
puts x
end
#=>
# Starting up the block!
# 1
# 2
# 3
# Exiting the block!
p e.map{ |x|
p x
}
如果要创建数组但仍能看到正确的执行顺序,可以使用:
Starting up the block!
1
2
3
Exiting the block!
[1, 2, 3]
输出:
double a=4;
double *x=&a;
double **y=&x;
cout <<x<<endl<<(y+1)<<endl<<(y+1)[0]<<endl<<y[1];
答案 1 :(得分:1)
我会稍微重构最后一行,所以可能会更清楚一点:
e = Enumerator.new do |y|
puts "Starting up the block!"
(1..3).each {|i| y << i }
puts "Exiting the block!"
end
a = e.to_a
# At this point "Starting up the block!" and "Exiting the block!"
# have been printed.
# Also the value of a is [1, 2, 3].
puts a # Prints [1, 2, 3]
上面的代码与您问题中的代码相同。发生了什么是枚举器不打印数组。最后一行是实际打印其值的人。
执行e.to_a
时,将运行Enumerator块。它将打印开始消息,将值添加到y
数组中并打印退出消息。完成后,a
变量将包含[1, 2, 3]
,最后puts
将最终打印出来。
希望这更有意义。
答案 2 :(得分:1)
你对此输出感到惊讶。
Starting up the block!
Exiting the block!
[1, 2, 3]
这很简单。评论将说明正在发生的事情。
e = Enumerator.new do |y|
# print first message
puts "Starting up the block!"
# append elements to array y (but don't print it)
(1..3).each {|i| y << i }
# print second message
puts "Exiting the block!"
end
# print the array
p e.to_a
答案 3 :(得分:0)
如果你想让你的代码更加纯粹,即不使用Ruby IO / File,(Ruby IO是Ruby中所有输入和输出的基础),那么按照下面的代码中的建议尝试它会给你直截了当的输出:
e = Enumerator.new do |y|
y << "start"
(1..3).each {|i| y << i }
y << "exit"
end
p e.to_a
这将是你的输出。
# ["start", 1, 2, 3, "exit"]
你可以试试这种方法。