RustPrimer
  • Introduction
  • 初识Rust
  • 安装Rust
    • Linux
    • Mac
    • Windows
    • 版本管理工具: rustup
  • 编辑器
    • 前期准备
    • vim
    • emacs
    • vscode
    • atom
    • sublime
    • visual studio
    • spacemacs
  • Rust快速入门
    • Rust旅程
    • 变量绑定与原生类型
    • 数组、动态数组和字符串
    • 结构体与枚举
    • 控制流
    • 函数与方法
    • 特性
    • 注释与文档
    • 输入输出流
  • Cargo项目管理器
  • 基本程序结构
    • 注释
    • 条件
    • 循环
  • 类型、运算符和字符串
    • 基础类型
    • 复合类型
    • 字符串类
    • 基础运算符和字符串格式化
  • 函数
    • 函数参数
    • 函数返回值
    • 语句和表达式
    • 高阶函数
  • 模式匹配
    • match关键字
    • 模式 pattern
  • 特征 Trait
    • trait关键字
    • trait对象
  • 泛型
  • 可变性、所有权、租借和生命期
    • 所有权
    • 引用和借用
    • 生命周期
  • 闭包
    • 闭包的语法
    • 闭包的实现
    • 闭包作为参数和返回值
  • 集合类型 Collections
    • 动态数组 Vec
    • 哈希表 HashMap
  • 迭代器
    • 迭代器、适配器、消费者
  • 模块和包系统、Prelude
    • 模块 module 和包 crate
    • Prelude
  • Option、Result与错误处理
  • 输入与输出
  • 宏系统
  • 堆、栈与Box
  • 几种智能指针
    • Rc, Arc
    • Mutex, RwLock
    • Cell, RefCell
  • 类型系统中的几个常见 Trait
    • Into/From 及其在 String 和 &str 互转上的应用
    • AsRef, AsMut
    • Borrow, BorrowMut, ToOwned
    • Deref 与 Deref coercions
    • Cow 及其在 String 和 &str 上的应用
  • Send 和 Sync
  • 并发,并行,多线程编程
    • 线程
    • 消息传递
    • 共享内存
    • 同步
    • 并行
  • Unsafe、原始指针
    • Unsafe
    • 原始指针
  • FFI
    • rust调用ffi函数
    • 将rust编译成库
  • 运算符重载
  • 属性和编译器参数
    • 属性
    • 编译器参数
  • Cargo参数配置
  • 测试与评测
    • 测试 (testing)
    • 评测 (benchmark)
  • 代码风格
  • Any与反射
  • 安全(safe)
  • 常用数据结构实现
    • 栈结构
    • 队列
    • 二叉树
    • 优先队列
    • 链表
    • 图结构
  • 标准库介绍
    • 系统命令:调用grep
    • 目录操作:简单grep
    • 网络模块:W回音
  • 实战篇
    • 实战:Json处理
    • 实战:Web 应用开发入门
    • 实战:使用Postgresql数据库
  • 附录-术语表
Powered by GitBook
On this page
  • for
  • while
  • loop
  • break 和 continue
  • label

Was this helpful?

  1. 基本程序结构

循环

  • for

  • while

  • loop

  • break 与 continue

  • label

for

for 语句用于遍历一个迭代器。

for var in iterator {
    code
}

Rust 迭代器返回一系列的元素,每个元素是循环中的一次重复。然后它的值与 var 绑定,它在循环体中有效。每当循环体执行完后,我们从迭代器中取出下一个值,然后我们再重复一遍。当迭代器中不再有值时,for 循环结束。

比如:

for x in 0..10 {
    println!("{}", x); // x: i32
}

输出

0
1
2
3
4
5
6
7
8
9

不熟悉迭代器概念的同学可能傻眼了,下面不妨用 C 形式的 for 语句做下对比:

// C 语言的 for 循环例子
for (x = 0; x < 10; x++) {
    printf( "%d\n", x );
}

两者输出是相同的,那么,为何 Rust 要这样来设计 for 语句呢?

  1. 简化边界条件的确定,减少出错;

  2. 减少运行时边界检查,提高性能。

即使对于有经验的 C 语言开发者来说,要手动控制要循环的每个元素也都是复杂并且易于出错的。

for 语句就是迭代器遍历的语法糖。

上述迭代器的形式虽好,但是好像在循环过程中,少了索引信息。Rust 考虑到了这一点,当你需要记录你已经循环了多少次了的时候,你可以使用 .enumerate() 函数。比如:

for (i,j) in (5..10).enumerate() {
    println!("i = {} and j = {}", i, j);
}

输出:

i = 0 and j = 5
i = 1 and j = 6
i = 2 and j = 7
i = 3 and j = 8
i = 4 and j = 9

再比如:

let lines = "Content of line one
Content of line two
Content of line three
Content of line four".lines();
for (linenumber, line) in lines.enumerate() {
    println!("{}: {}", linenumber, line);
}

输出:

0: Content of line one
1: Content of line two
2: Content of line three
3: Content of line four

关于迭代器的知识,详见 迭代器 章节。

while

Rust 提供了 while 语句,条件表达式为真时,执行语句体。当你不确定应该循环多少次时可选择 while。

while expression {
    code
}

比如:

let mut x = 5; // mut x: i32
let mut done = false; // mut done: bool

while !done {
    x += x - 3;

    println!("{}", x);

    if x % 5 == 0 {
        done = true;
    }
}

loop

有一种情况,我们经常会遇到,就是写一个无限循环:

while true {
    // do something
}

针对这种情况,Rust 专门优化提供了一个语句 loop。

loop {
    // do something
}

loop 与 while true 的主要区别在编译阶段的静态分析。

比如说,如下代码:

let mut a;
loop {
     a = 1;
     // ... break ...
}
do_something(a)

如果是loop循环,编译器会正确分析出变量a会被正确初始化,而如果换成while true,则会发生编译错误。这个微小的区别也会影响生命周期分析。

break 和 continue

与 C 语言类似,Rust 也提供了 break 和 continue 两个关键字用来控制循环的流程。

  • break 用来跳出当前层的循环;

  • continue 用来执行当前层的下一次迭代。

像上面那个 while 例子:

let mut x = 5;
let mut done = false;

while !done {
    x += x - 3;

    println!("{}", x);

    if x % 5 == 0 {
        done = true;
    }
}

可以优化成:

let mut x = 5;

loop {
    x += x - 3;

    println!("{}", x);

    if x % 5 == 0 { break; }
}

这样感觉更直观一点。

下面这个例子演示 continue 的用法:

for x in 0..10 {
    if x % 2 == 0 { continue; }

    println!("{}", x);
}

它的作用是打印出 0~9 的奇数。结果如下:

1
3
5
7
9

label

你也许会遇到这样的情形,当你有嵌套的循环而希望指定你的哪一个 break 或 continue 该起作用。就像大多数语言,默认 break 或 continue 将会作用于当前层的循环。当你想要一个 break 或 continue 作用于一个外层循环,你可以使用标签来指定你的 break 或 continue 语句作用的循环。

如下代码只会在 x 和 y 都为奇数时打印他们:

'outer: for x in 0..10 {
    'inner: for y in 0..10 {
        if x % 2 == 0 { continue 'outer; } // continues the loop over x
        if y % 2 == 0 { continue 'inner; } // continues the loop over y
        println!("x: {}, y: {}", x, y);
    }
}
Previous条件Next类型、运算符和字符串

Last updated 5 years ago

Was this helpful?