欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
全部教程·
Rust语言·
通过例子学Rust
[目录]
·
8.5.7 if let 语句
Rust 简介
1. Hello World
1.1. 注释
1.2. 格式化输出
1.2.1 调试(debug)
1.2.2 显示(display)
1.2.3 测试实例:List
1.2.4 格式化
2. 原生类型
2.1. 字面量和运算符
2.2. 元组
2.3. 数组和切片
3. 自定义类型
3.1. 结构体
3.2. 枚举
3.2.1 使用 use
3.2.2 C 风格用法
3.2.3 测试实例:链表
3.3. 常量
4. 变量绑定
4.1. 可变变量
4.2. 作用域和遮蔽
4.3. 变量先声明
4.4. 冻结
5. 类型系统
5.1. 类型转换
5.2. 字面量
5.3. 类型推断
5.4. 别名
6. 类型转换
6.1. From 和 Into
6.2. TryFrom 和 TryInto
6.3. ToString 和 FromStr
7. 表达式
8. 流程控制
8.1. 条件语句 if/else
8.2. 循环语句 loop
8.2.1. 嵌套循环和标签
8.2.2 loop 循环返回
8.3. while 循环
8.4. for 循环
8.5. match 匹配
8.5.1 match 解构元组
8.5.2 match 解构枚举
8.5.3 match 解构指针
8.5.4 match 解构结构体
8.5.5 卫语句
8.5.6 绑定
8.5.7 if let 语句
8.5.8 while let 语句
9. Rust 函数
9.1 Rust 方法
9.2 Rust 闭包
9.2.1 捕获变量
9.2.2 作为输入参数
9.2.3 类型匿名
9.2.4 输入函数
9.2.5 作为输出参数
9.2.6 Iterator::any
9.2.7 Iterator::find
9.3. 高阶函数
9.4. 发散函数
10. 模块
10.1. 可见性
10.2. 结构体的可见性
10.3. use 声明
10.4. super 和 self
10.5. 文件分层
11. crate
11.1. 库
11.2. 使用库
12. cargo
12.1. 依赖
12.2. 约定规范
12.3. 测试
12.4. 构建脚本
13. 属性
13.1 死代码
13.2 crate
13.3 cfg
13.4 自定义条件
14. 泛型
14.1. 函数
14.2. 实现
14.3. trait
14.4. 约束
14.4.1 空约束
14.5. 多重约束
14.6. where 子句
14.7. newtype 惯用法
14.8. 关联项
14.8.1 存在问题
14.9. 虚类型参数
14.9.1 单位检查
Rust 简介
1. Hello World
1.1. 注释
1.2. 格式化输出
1.2.1 调试(debug)
1.2.2 显示(display)
1.2.3 测试实例:List
1.2.4 格式化
2. 原生类型
2.1. 字面量和运算符
2.2. 元组
2.3. 数组和切片
3. 自定义类型
3.1. 结构体
3.2. 枚举
3.2.1 使用 use
3.2.2 C 风格用法
3.2.3 测试实例:链表
3.3. 常量
4. 变量绑定
4.1. 可变变量
4.2. 作用域和遮蔽
4.3. 变量先声明
4.4. 冻结
5. 类型系统
5.1. 类型转换
5.2. 字面量
5.3. 类型推断
5.4. 别名
6. 类型转换
6.1. From 和 Into
6.2. TryFrom 和 TryInto
6.3. ToString 和 FromStr
7. 表达式
8. 流程控制
8.1. 条件语句 if/else
8.2. 循环语句 loop
8.2.1. 嵌套循环和标签
8.2.2 loop 循环返回
8.3. while 循环
8.4. for 循环
8.5. match 匹配
8.5.1 match 解构元组
8.5.2 match 解构枚举
8.5.3 match 解构指针
8.5.4 match 解构结构体
8.5.5 卫语句
8.5.6 绑定
8.5.7 if let 语句
8.5.8 while let 语句
9. Rust 函数
9.1 Rust 方法
9.2 Rust 闭包
9.2.1 捕获变量
9.2.2 作为输入参数
9.2.3 类型匿名
9.2.4 输入函数
9.2.5 作为输出参数
9.2.6 Iterator::any
9.2.7 Iterator::find
9.3. 高阶函数
9.4. 发散函数
10. 模块
10.1. 可见性
10.2. 结构体的可见性
10.3. use 声明
10.4. super 和 self
10.5. 文件分层
11. crate
11.1. 库
11.2. 使用库
12. cargo
12.1. 依赖
12.2. 约定规范
12.3. 测试
12.4. 构建脚本
13. 属性
13.1 死代码
13.2 crate
13.3 cfg
13.4 自定义条件
14. 泛型
14.1. 函数
14.2. 实现
14.3. trait
14.4. 约束
14.4.1 空约束
14.5. 多重约束
14.6. where 子句
14.7. newtype 惯用法
14.8. 关联项
14.8.1 存在问题
14.9. 虚类型参数
14.9.1 单位检查
Rust if let 语句
在一些场合下,用 match 匹配枚举类型并不优雅。比如:
#![allow(unused)]
fn main() {
// 将 `optional` 定为 `Option` 类型
let optional = Some(7);
match optional {
Some(i) => {
println!("This is a really long string and `{:?}`", i);
// ^ 行首需要 2 层缩进。这里从 optional 中解构出 `i`。
// 译注:正确的缩进是好的,但并不是 “不缩进就不能运行” 这个意思。
},
_ => {},
// ^ 必须有,因为 `match` 需要覆盖全部情况。不觉得这行很多余吗?
};
}
if let 在这样的场合要简洁得多,并且允许指明数种失败情形下的选项:
fn main() {
// 全部都是 `Option<i32>` 类型
let number = Some(7);
let letter: Option<i32> = None;
let emoticon: Option<i32> = None;
// `if let` 结构读作:若 `let` 将 `number` 解构成 `Some(i)`,则执行
// 语句块(`{}`)
if let Some(i) = number {
println!("Matched {:?}!", i);
}
// 如果要指明失败情形,就使用 else:
if let Some(i) = letter {
println!("Matched {:?}!", i);
} else {
// 解构失败。切换到失败情形。
println!("Didn't match a number. Let's go with a letter!");
};
// 提供另一种失败情况下的条件。
let i_like_letters = false;
if let Some(i) = emoticon {
println!("Matched {:?}!", i);
// 解构失败。使用 `else if` 来判断是否满足上面提供的条件。
} else if i_like_letters {
println!("Didn't match a number. Let's go with a letter!");
} else {
// 条件的值为 false。于是以下是默认的分支:
println!("I don't like letters. Let's go with an emoticon :)!");
};
}
同样,可以用 if let 匹配任何枚举值:
// 以这个 enum 类型为例
enum Foo {
Bar,
Baz,
Qux(u32)
}
fn main() {
// 创建变量
let a = Foo::Bar;
let b = Foo::Baz;
let c = Foo::Qux(100);
// 变量 a 匹配到了 Foo::Bar
if let Foo::Bar = a {
println!("a is foobar");
}
// 变量 b 没有匹配到 Foo::Bar,因此什么也不会打印。
if let Foo::Bar = b {
println!("b is foobar");
}
// 变量 c 匹配到了 Foo::Qux,它带有一个值,就和上面例子中的 Some() 类似。
if let Foo::Qux(value) = c {
println!("c is {}", value);
}
}
另一个好处是:if let 允许匹配枚举非参数化的变量,即枚举未注明 #[derive(PartialEq)],我们也没有为其实现 PartialEq。在这种情况下,通常 if Foo::Bar==a 会出错,因为此类枚举的实例不具有可比性。但是,if let 是可行的。
你想挑战一下吗?使用 if let修复以下示例:
// 该枚举故意未注明 `#[derive(PartialEq)]`,
// 并且也没为其实现 `PartialEq`。这就是为什么下面比较 `Foo::Bar==a` 会失败的原因。
enum Foo {Bar}
fn main() {
let a = Foo::Bar;
// 变量匹配 Foo::Bar
if Foo::Bar == a {
// ^-- 这就是编译时发现的错误。使用 `if let` 来替换它。
println!("a is foobar");
}
}
下一章:Rust while let 语句
和 if let 类似,while let 也可以把别扭的 match 改写得好看一些。考虑下面这段使 i 不断增加的代码:#![allow(unused)]fn main() {// 将 `option ...
AI 中文社