跳到內容

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 迴圈正常結束(因為其條件變為 false),則值為 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