循环是一种控制结构,它让代码可以基于给定的条件重复执行。
while 循环while 循环是一种控制结构,它让代码可以基于给定的条件重复执行。
只要条件的求值结果为 truthy,while 循环里的代码就会一直执行下去。
当事先不知道迭代次数时,常常会用到 while 循环;其实任何需要循环的场景都可以用它。
条件会在循环内的代码执行之前求值,也就是说,如果条件为 false,循环内的代码就永远不会执行。
i = 0
while i < 3
puts i
i += 1
end
# Output:
# 0
# 1
# 2
如果想迭代一个字符串,可以按字符串的长度来循环。
str = "Hello"
i = 0
while i < str.size
puts str[i]
i += 1
end
# Output:
# H
# e
# l
# l
# o
until 循环until 循环和 while 循环的工作方式相同,区别在于:循环内的代码会一直执行,直到条件的求值结果为 truthy。
这和 if 与 unless 之间的区别是一样的。
i = 0
until i == 3
puts i
i += 1
end
while 循环一个常见的错误是进入“无限循环”,它永远不会退出。
无限循环可能源于某个条件_永远_不会求值为 truthy 或 falsey。
这通常是编程失误造成的,比如忘记让循环变量自增。
但有时,无限循环是实现程序逻辑最清晰的方式。
又或者,永远循环下去是必要的;比如,HTTP 服务器会等待一个传入的连接,处理它,然后再等待下一个连接。
breakbreak 关键字可以用来提前退出循环。
当你希望在满足某些条件时提前退出循环,这会很方便。
i = 0
while i <= 3
puts i
i += 1
if i == 2
break
end
end
# Output:
# 0
# 1
nextnext 关键字可以用来跳到循环的下一次迭代。
当你希望跳过循环中的某些迭代时,这会很方便。
i = 0
while i <= 3
i += 1
if i == 2
next
end
puts i
end
# Output:
# 1
# 3
循环中变量的类型可能会发生变化。
在下面的例子中,a 的类型是 Int32 | String,因为在循环的前一部分中,它既可能是 Int32,也可能是 String。
变量 a 只在循环的前一部分带有 Int32 | String 类型,因为循环开始时它持有 Int32,而在第二次迭代中,它持有 String。
这套多类型系统稍后会有详细讲解。
但由于我们可以确定循环的后一部分只会持有 String,所以在循环的后一部分中,a 的类型是 String。
在运行时,它绝不会同时持有 Int32 和 String。
i = 0
a = 4
while i < 3
p typeof(a)
# => Int32 | String
a = "4"
p typeof(a)
# => String
i += 1
end
while 用作表达式while 可以用作表达式,也就是说,它可以作为变量的值。
它返回的值,是通过 break 关键字给出的那个值。
它不会返回循环中最后一个表达式的值。
a = while true
break 1
end
p a
# => 1
i = 0
a = while i == 0
i += 1
1
end
p a
# => nil