跳至内容

while

一个 while 只要它的条件为 真值,就会执行它的主体。

while some_condition
  do_this
end

首先测试条件,如果条件为 真值,则执行主体。也就是说,主体可能永远不会被执行。

if 类似,如果 while 的条件是一个变量,则该变量在主体内部保证不会为 nil。如果条件是 var.is_a?(Type) 测试,则 var 在主体内部保证为 Type 类型。如果条件是 var.responds_to?(:method),则 var 保证为响应该方法的类型。

变量在 while 之后的类型取决于它在 while 之前的类型以及它在离开 while 主体之前的类型

a = 1
while some_condition
  # a : Int32 | String
  a = "hello"
  # a : String
  a.size
end
# a : Int32 | String

在循环结束时检查条件

如果您需要至少执行一次主体,然后检查中断条件,您可以这样做

while true
  do_something
  break if some_condition
end

或者使用标准库中的 loop

loop do
  do_something
  break if some_condition
end

作为表达式

while 的值是退出 while 主体的 break 表达式的值

a = 0
x = while a < 5
  a += 1
  break "four" if a == 4
  break "three" if a == 3
end
x # => "three"

如果 while 循环正常结束(因为它的条件变为假),则值为 nil

x = while 1 > 2
  break 3
end
x # => nil

没有参数的 break 表达式也返回 nil

x = while 2 > 1
  break
end
x # => nil

具有多个参数的 break 表达式将打包到 Tuple 实例中

x = while 2 > 1
  break 3, 4
end
x         # => {3, 4}
typeof(x) # => Tuple(Int32, Int32)

while 的类型是主体中所有 break 表达式的类型的并集,加上 Nil,因为条件可能失败

x = while 1 > 2
  if rand < 0.5
    break 3
  else
    break '4'
  end
end
typeof(x) # => (Char | Int32 | Nil)

但是,如果条件正好是 true 字面量,则其效果将从返回值和返回类型中排除

x = while true
  break 1
end
x         # => 1
typeof(x) # => Int32

特别是,没有 breakwhile true 表达式具有 NoReturn 类型,因为循环永远不会在同一范围内退出

x = while true
  puts "yes"
end
x         # unreachable
typeof(x) # => NoReturn