13-循环表达式
6 分钟阅读
译文 · 基于 The Rust Reference
原文链接: https://doc.rust-lang.org/reference/expressions/loop-expr.html
r[expr.loop]
循环表达式
r[expr.loop.syntax]
LoopExpression ->
LoopLabel? (
InfiniteLoopExpression
| PredicateLoopExpression
| IteratorLoopExpression
| LabelBlockExpression
)
r[expr.loop.intro] Rust 支持四种循环表达式:
loop表达式表示无限循环。while表达式循环直到谓词为假。for表达式从迭代器中取出值,循环直到迭代器为空。- [带标签的块表达式][expr.loop.block-labels]恰好运行一次循环,但允许用
break提前退出。
r[expr.loop.break-label]
所有四种循环都支持 break 表达式和标签。
r[expr.loop.continue-label]
除带标签的块表达式外,都支持 continue 表达式。
r[expr.loop.explicit-result]
只有 loop 和带标签的块表达式支持求值为非平凡值。
r[expr.loop.infinite]
无限循环
r[expr.loop.infinite.syntax]
InfiniteLoopExpression -> `loop` BlockExpression
r[expr.loop.infinite.intro]
loop 表达式会持续重复执行其循环体:loop { println!("I live."); }。
r[expr.loop.infinite.diverging]
没有关联 break 表达式的 loop 表达式是发散的,类型为 !。
r[expr.loop.infinite.break]
含有关联 break 表达式的 loop 表达式可能终止,其类型必须与 break 表达式的值兼容。
r[expr.loop.while]
谓词循环
r[expr.loop.while.syntax]
PredicateLoopExpression -> `while` Conditions BlockExpression
r[expr.loop.while.intro]
while 循环表达式允许在一组条件保持为真时重复求值一个块。
r[expr.loop.while.condition]
条件操作数必须是具有布尔类型的[表达式][Expression],或是条件式 let 匹配。若所有条件操作数都求值为 true,且所有 let 模式都成功匹配其被检视表达式,则执行循环体块。
r[expr.loop.while.repeat] 循环体成功执行后,会重新求值条件操作数,以决定是否再次执行循环体。
r[expr.loop.while.exit]
若任一条件操作数求值为 false,或任一 let 模式未能匹配其被检视表达式,则不执行循环体,执行从 while 表达式之后继续。
r[expr.loop.while.eval]
while 表达式求值为 ()。
示例:
| |
r[expr.loop.while.let]
while let 模式
r[expr.loop.while.let.intro]
while 条件中的 let 模式允许在模式匹配成功时把新变量绑定到作用域中。以下示例演示了使用 let 模式的绑定:
| |
r[expr.loop.while.let.desugar]
while let 循环等价于如下包含 match 表达式的 loop 表达式。
| |
等价于
| |
r[expr.loop.while.let.or-pattern]
可以用 | 运算符指定多个模式。其语义与 match 表达式中的 | 相同:
| |
r[expr.loop.while.chains]
while 条件链
r[expr.loop.while.chains.intro]
多个条件操作数可以用 && 分隔。其语义和限制与 if 条件链相同。
以下示例演示了串联多个表达式、混合 let 绑定与布尔表达式,并且后续表达式可以引用先前表达式中的模式绑定:
| |
r[expr.loop.for]
迭代器循环
r[expr.loop.for.syntax]
IteratorLoopExpression ->
`for` Pattern `in` Expression _except [StructExpression]_ BlockExpression
r[expr.loop.for.intro]
for 表达式是一种语法构造,用于遍历由 std::iter::IntoIterator 的实现所提供的元素。
r[expr.loop.for.condition]
若迭代器产生一个值,则将该值与不可反驳模式匹配,执行循环体,然后将控制返回到 for 循环的头部。若迭代器为空,则 for 表达式完成。
遍历数组内容的 for 循环示例:
| |
遍历一系列整数的 for 循环示例:
| |
r[expr.loop.for.desugar]
for 循环等价于如下包含 match 表达式的 loop 表达式:
| |
等价于
| |
r[expr.loop.for.lang-items]
此处的 IntoIterator、Iterator 和 Option 始终是标准库中的项,而不是当前作用域中这些名字所解析到的任何其它项。
变量名 next、iter 和 val 仅用于说明,用户并不能键入这些实际名字。
注意 外层的
match用于确保iter_expr中的任何临时值在循环结束前不会被丢弃。next在赋值前先声明,是为了更经常地正确推断类型。
r[expr.loop.label]
循环标签
r[expr.loop.label.syntax]
LoopLabel -> LIFETIME_OR_LABEL `:`
r[expr.loop.label.intro]
循环表达式可以可选地带有一个_标签_。标签写成循环表达式之前的生命周期,例如 'foo: loop { break 'foo; }、'bar: while false {}、'humbug: for _ in 0..0 {}。
r[expr.loop.label.control-flow]
若存在标签,则嵌套在该循环内的带标签 break 和 continue 表达式可以退出该循环,或将控制返回到其头部。见 break 表达式和 continue 表达式。
r[expr.loop.label.ref] 标签遵循与局部变量相同的卫生性和遮蔽规则。例如,下面的代码会打印 “outer loop”:
| |
'_ 不是合法的循环标签。
r[expr.loop.break]
break 表达式
r[expr.loop.break.syntax]
BreakExpression -> `break` LIFETIME_OR_LABEL? Expression?
r[expr.loop.break.intro]
遇到 break 时,立即终止所关联循环体的执行,例如:
| |
r[expr.loop.break.diverging]
break 表达式是发散的,类型为 !。
r[expr.loop.break.label]
break 表达式通常关联到包围它的最内层 loop、for 或 while 循环,但可以使用标签指定受影响的外围循环。示例:
| |
r[expr.loop.break.value]
break 表达式只允许出现在循环体中,形式为 break、break 'label,或(见下文)break EXPR 或 break 'label EXPR。
r[expr.loop.break-value.implicit-value]
在[带 break 表达式的 loop][expr.loop.break-value]或带标签的块表达式中,不带表达式的 break 等价于 break ()。
r[expr.loop.block-labels]
带标签的块表达式
r[expr.loop.block-labels.syntax]
LabelBlockExpression -> BlockExpression
r[expr.loop.block-labels.intro]
带标签的块表达式与块表达式完全相同,只是允许在块内使用 break 表达式。
r[expr.loop.block-labels.break]
与循环不同,带标签块表达式内的 break 表达式必须带有标签(即标签不是可选的)。
r[expr.loop.block-labels.label-required] 同样,带标签的块表达式必须以标签开头。
| |
r[expr.loop.block-labels.type] 带标签块表达式的类型是所有 break 操作数与最终操作数的最小上界。若省略最终操作数,则最终操作数的类型默认为单元类型;除非该块[发散][expr.block.diverging],此时为 never 类型。
| |
r[expr.loop.continue]
continue 表达式
r[expr.loop.continue.syntax]
ContinueExpression -> `continue` LIFETIME_OR_LABEL?
r[expr.loop.continue.intro]
遇到 continue 时,立即终止所关联循环体的当前迭代,将控制返回到循环头部。
r[expr.loop.continue.diverging]
continue 表达式是发散的,类型为 !。
r[expr.loop.continue.while]
对于 while 循环,头部是控制该循环的条件操作数。
r[expr.loop.continue.for]
对于 for 循环,头部是控制该循环的调用表达式。
r[expr.loop.continue.label]
与 break 一样,continue 通常关联到最内层外围循环,但可以使用 continue 'label 指定受影响的循环。
r[expr.loop.continue.in-loop-only]
continue 表达式只允许出现在循环体中。
r[expr.loop.break-value]
break 与循环值
r[expr.loop.break-value.intro]
当与 loop 关联时,break 表达式可以通过 break EXPR 或 break 'label EXPR 的形式从该循环返回一个值,其中 EXPR 是一个表达式,其结果从该 loop 返回。例如:
| |
r[expr.loop.break-value.type]
带关联 break 表达式的 loop 的类型是所有 break 操作数的最小上界。
| |
r[expr.loop.break-value.diverging]
带关联 break 表达式的 loop 在任一 break 操作数不发散时不会发散。若所有 break 操作数都发散,则该 loop 表达式也发散。
| |
| |