拓冰建站拓冰建站
首页 / 资讯中心 / 正文

comprehensive-rust 控制流精讲:深入理解 Rust 的 `loop` 无限循环

comprehensive-rust 控制流精讲深入理解 Rust 的loop无限循环【免费下载链接】comprehensive-rustThis is the Rust course used by the Android team at Google. It provides you the material to quickly teach Rust.项目地址: https://gitcode.com/GitHub_Trending/co/comprehensive-rustloop是 Rust 中最直白的循环关键字它无条件地无限重复循环体直到遇到break显式退出。在 Google Android 团队维护的 Rust 课程仓库 comprehensive-rust 中它是控制流三兄弟while、loop、for里唯一永不自行终止的构造也是唯一能带返回值离开的循环。读完本文你将掌握loop的完整语法、break/continue与标签的配合方式以及它在服务器常驻、嵌入式 panic 处理、异步状态机等真实场景中的典型用法。loop的基本形态永远重复直到break课程的 loop.md 开门见山loop语句只是永远循环直到出现break。它不需要任何条件表达式loop { ... }本身即完整语句。课程给出的示例通过计数器演示了最基础用法fn main() { let mut i 0; loop { i 1; dbg!(i); if i 100 { break; } } }逐行拆解这段代码可以提炼出loop的核心要素循环体没有任何前置条件与while不同loop在进入循环体之前不会检查任何布尔表达式天然是先做再说的语义。计数器需要mut变量i声明为let mut i 0;因为在循环体内执行i 1会修改它。Rust 默认不可变的规则同样作用于循环计数器。退出依赖breakif i 100 { break; }是唯一的出口。若删除这行程序将无限打印递增的i永不结束。dbg!用于调试观察dbg!(i)是标准库调试宏会向 stderr 打印表达式及其值并原样返回该值。课程在 macros.md 中专门介绍过它适合在讲课或调试时观察循环进度。整个控制流专题在 loops.md 中明确定位了三种循环关键字的分工while在条件为真时反复执行for遍历范围或集合而loop则用于没有条件、纯粹靠break决定何时离开的场景。loop与while true的关系课程details折叠块给出了一个重要等价关系loop的工作方式就像一个while true循环。也就是说下面两种写法行为一致// 写法一loop loop { // 处理请求... break; // 必须显式退出 } // 写法二while true不推荐Rust 编译器会建议改用 loop let mut cond true; while cond { // 处理请求... cond false; // 或直接 break }两者都要求循环体内有退出路径否则就是死循环。但 Rust 社区和本课程都更推荐loop原因有二意图更清晰loop明确表达这个循环要一直跑退出条件在循环体内部决定而while true仍然暗示存在条件检查这一环节。配合表达式返回值loop是 Rust 中唯一能保证只在break处返回的循环构造因此它可以作为一个表达式产出值详见下文而while做不到这一点。课程给出的经典应用场景是服务器一个常驻进程用loop不断接受连接、处理请求理论上永不退出只有在收到关闭信号时才break。这类代码在并发专题如 async.md 的聊天服务器、threads.md 的线程示例中反复出现。break与continue控制循环节奏要驾驭loop必须掌握break和continue这对控制关键字。break-continue.md 给出了一个同时使用两者的完整示例fn main() { let mut i 0; loop { i 1; if i 5 { break; } if i % 2 0 { continue; } dbg!(i); } }执行流程分析continue立即开始下一次迭代。当i为偶数时continue跳过后面的dbg!(i)直接进入下一轮i 1。break完全退出循环。当i超过 5 时循环终止。最终输出i 1、i 3、i 5偶数被continue跳过i 6时因i 5直接break。这段代码展示了二者的分工continue处理本次迭代该跳过的情况break处理整个循环该结束的情况。loop是唯一能返回值的循环break-continue.md的details部分强调了一个语言层面的关键差异loop是唯一可以返回非平凡non-trivial值的循环构造。原因在于类型系统loop保证只在break语句处返回所以break可以携带一个表达式作为整个loop表达式的求值结果而while和for还可能在条件失败时自然退出此时无值可返回因此它们不能产生有意义的值。fn main() { let mut n 0; let result loop { n 1; if n 10 { break n * 2; // break 携带值作为 loop 的结果 } }; println!(result {result}); // 输出 20 }注意break n * 2后面是分号它终止循环的同时把n * 2作为loop表达式的值赋给result。这种写法常用于反复尝试直到满足条件并把最终值拿出来的场景例如重试逻辑、读取用户输入直到合法等。嵌套循环与标签精确跳出外层当循环嵌套时普通的break只能退出最内层循环。要一次跳出多层需要用标签label。labels.md 展示了这一机制fn main() { let s [[5, 6, 7], [8, 9, 10], [21, 15, 32]]; let mut elements_searched 0; let target_value 10; outer: for i in 0..2 { for j in 0..2 { elements_searched 1; if s[i][j] target_value { break outer; // 直接跳出外层循环 } } } dbg!(elements_searched); }要点标签写法是outer:放在循环关键字之前。break outer;从两层循环中一次性跳出elements_searched最终值为 6[5,6,7,8,9,10]共 6 个元素被检查。continue同样可以携带标签用于跳过外层循环的当前迭代。更进一步课程指出标签break也能作用于任意代码块而不只是循环fn main() { label: { break label; println!(This line gets skipped); } println!(after block); }break label;会直接离开被标记的{}块块内println!永远不会执行程序输出after block。这一特性在需要从嵌套逻辑中提前整体退出时非常实用。真实场景一嵌入式裸机中的loop {}loop最常见的实战形态之一是程序结束后的停驻点。在课程的裸机bare metal章节中main_minimal.rs 的 panic 处理函数这样写#[panic_handler] fn panic(info: PanicInfo) - ! { error!({}, info); system_off::Hvc().unwrap(); loop {} // 永不返回处理器在此停驻 }这里的loop {}是空的无限循环没有任何break。它在无操作系统的no_std环境中扮演系统停机的角色panic 后处理器没有可退出的地方loop {}保证程序在错误后不会执行未定义行为而是稳定地停住。这也是loop类型为!永不返回类型的直接体现正因如此loop {}可以作为- !函数的末尾表达式。类似的模式在异步与并发代码中同样常见例如事件循环、任务轮询的主干。真实场景二异步状态机中的loop match在 state-machine.md 中课程展示了 Rust 如何把async fn编译成一个内部状态机而其poll方法的主干正是loopimpl Future for TwoD10 { type Output u32; fn poll(mut self: Pinmut Self, ctx: mut Context) - PollSelf::Output { loop { match *self { TwoD10::Init { modifier } { /* 发起第一次掷骰 */ } TwoD10::FirstRoll { modifier, fut } { /* 等待第一次结果 */ } TwoD10::SecondRoll { modifier, first_roll, fut } { return Poll::Ready(first_roll second_roll modifier); } } } } }loop包裹match是 Rust 中非常经典的习惯用法loop-match 模式每一轮迭代根据当前状态推进一步状态不满足条件就继续循环直到达到终态后用return或break带值离开。这展示了loop不仅仅用于服务器永远跑也用于反复推进直到完成的算法式循环。与for、while的分工何时该用loop回到 loops.md 的框架三种循环的选用建议可以总结为循环语义适用场景能否返回值while条件为真时执行有明确前置/运行时条件否非平凡值loop无条件重复靠break退出常驻服务、重试、状态机、panic 停驻是仅loopfor遍历范围或集合迭代元素配合迭代器否非平凡值其中for底层依赖迭代器iterator机制课程在 for.md 中说明并在后续专门的迭代器章节iterators.md深入展开。若你的循环有一个范围可遍历首选for若有一个条件可判断首选while若循环必须无条件先跑起来、靠内部逻辑决定何时退出或携带什么值退出那就该用loop。配套练习Collatz 序列为了巩固控制流知识课程在 exercise.md 安排了 Collatz 序列长度计算练习对任意正整数 n若为偶数则 n n/2若为奇数则 n 3n 1直到 n 为 1统计序列长度。其官方解答见 exercise.rs 与 solution.md使用while n 1实现/// Determine the length of the collatz sequence beginning at n. fn collatz_length(mut n: i32) - u32 { let mut len 1; while n 1 { n if n % 2 0 { n / 2 } else { 3 * n 1 }; len 1; } len } fn main() { println!(Length: {}, collatz_length(11)); // should be 15 }这个练习与本文主题直接相关如果改用loop实现写法是loop { ... if n 1 { break len; } ... }——这正是用break携带返回值退出loop的实战演练。解答中同时体现了mut参数、if作为表达式、隐式返回三个 Rust 特性。课程还提醒该函数对n 0的输入可能陷入死循环或溢出i32在 n 增长过大时溢出这正是loop陷阱的绝佳教学素材——无限循环能力越强越要确保存在可靠的退出条件。小结loop无条件无限循环退出完全依赖break等价于while true但语义更清晰、能力更强。break可携带表达式使loop成为唯一能返回非平凡值的循环continue用于跳过本次迭代。嵌套循环可用label标签配合break label/continue label精确控制跳出层次标签也可用于普通代码块。实战形态包括服务器常驻循环、loop {}停机停驻main_minimal.rs、异步状态机的loop match推进模式。相关课程材料可在 loops.md、break-continue.md、labels.md、exercise.md 中继续深入所有示例均可在课程仓库内直接阅读与运行。【免费下载链接】comprehensive-rustThis is the Rust course used by the Android team at Google. It provides you the material to quickly teach Rust.项目地址: https://gitcode.com/GitHub_Trending/co/comprehensive-rust创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门