true:TrueClass 的未定义方法“each”(NoMethodError)

undefined method `each' for true:TrueClass (NoMethodError)

我正在 Ruby 中编写一个 for 循环,它循环遍历数组的元素,直到没有更多元素可供读取或满足条件为止。这是我的实现:

# 'all' is an array

exists = false

for i in all && !exists
  exists = all[i].has_card
end

正如标题所说,我遇到了这个运行时错误:

undefined method `each' for true:TrueClass (NoMethodError)

我是 Ruby 的新手,但我猜问题是 for 循环试图遍历 all!existstrue。我怎样才能编写一个按我想要的方式工作的 for?

编辑:如果它作为澄清,这就是我在 C++ 中实现它的方式:

for (int i=0; i<all.size() && !exists; i++) { /*...*/ }

首先,呃。 for 从未使用过;它是 Ruby 的 "moist"。 :)

for item in items ... end被Ruby执行,就好像你写了items.each do |item| ... end一样。 (这实际上是 Rubyists 首先会写的。)这是相关的;所以等一下。

您的行解析为:

for i in (all && (!exists))

existsfalse时,!existstrue。现在,&& 运算符将检查第一个参数是否为真;如果不是,它 returns 它;如果是,它是 returns 第二个参数。由于 all 可能是真实的,因此 all && true returns 第二个参数 - true。

现在请记住,您的代码行实际上在后台调用了您正在迭代的集合的 each 方法。而您的 "collection" 是 true — 根本不是集合。您不能迭代 true.

如果你不想使用break(这有点不合理,你可以引用我),你可以使用Enumerable模块中的其他方法。例如:

all.take_while { |item| !item.has_card }.each do |item|
  # ...
end

这比 break 方法慢一点,因为它会构造一个中间数组,其中只包含前 N 个没有卡片的项目,稍后将对其进行迭代,但担心的是过早的优化。

编辑:不幸的是,塞巴斯蒂安删除了他们的答案,它有正确的成语(我可能会比上面的那个更早写,尽管它完全取决于具体情况),所以我在这里重复:

all.each do |item|
  break if item.has_card
  # ...
end