条件判断
条件判断
if判断
rust不会隐式的将数值转换布尔值
单分支if
fn main() {
let score = 85;
if score >= 60 {
println!("及格");
}
}
if加else
fn main() {
let score = 45;
if score >= 60 {
println!("及格");
} else {
println!("不及格")
}
}
else-if用法
fn main() {
let score = 45;
if score >= 90 {
println!("优秀");
} else if score >= 80 {
println!("良好");
} else if score >= 60 {
println!("及格");
} else {
println!("不及格");
}
}
三元运算
返回值需要同一种类型
fn main() {
// 类似三元运算符(注意需要返回相同的类型)
let a = 3;
let b = if a > 5 { 1 } else { -1 };
// let b = if a > 5 { "11" } else { -1 }; 错误,返回类不一样
// let b = if a > 5 { 1 }; 错误,else默认返回()空元组
println!("b: {b}");
}
match判断
基础用法
替代简单 switch(匹配字面量)
fn main() {
let day = 3;
// match 匹配字面量,每个分支用 `=>` 分隔(模式 => 逻辑)
match day {
1 => println!("星期一"),
2 => println!("星期二"),
3 => println!("星期三"),
4 => println!("星期四"),
5 => println!("星期五"),
6 => println!("星期六"),
7 => println!("星期日"),
// 通配符 _:匹配所有未明确列出的情况,满足穷尽性要求
// 必须放在最后,因为 match 是按顺序匹配的
_ => println!("无效的日期"),
}
}
多模式匹配
用
|分隔,“或” 逻辑
fn main() {
let day = 6;
match day {
// 多模式匹配:1-5 都匹配该分支
1 | 2 | 3 | 4 | 5 => println!("工作日"),
// 多模式匹配:6-7 都匹配该分支
6 | 7 => println!("休息日"),
_ => println!("无效的日期"),
}
}
范围匹配
fn main() {
let score = 85;
match score {
90..=100 => println!("优秀"),
80..=89 => println!("良好"),
60..=79 => println!("及格"),
0..=59 => println!("不及格"),
_ => println!("无效的分数"),
}
}
作为表达式返回值
fn main() {
let score = 85;
// 接受返回值
let grade = match score {
90..=100 => "优秀",
80..=89 => "良好",
60..=79 => "及格",
0..=59 => "不及格",
_ => "无效分数",
};
println!("成绩评级:{}", grade); // 输出:成绩评级:良好
}
匹配枚举
在匹配枚举中关联的匿名结构体(如
Message::Move { x, y })时,字段名x和y必须和枚举定义时的字段名完全一致;而对于元组形式的关联数据(如
Message::ChangeColor(r, g, b)),变量名则可以随意命名,无需和任何 “固定字段名” 保持一致
// 定义一个简单的枚举(表示不同的消息类型)
enum Message {
Quit, // 无关联数据
Move { x: i32, y: i32 }, // 关联匿名结构体
Write(String), // 关联 String 类型
ChangeColor(i32, i32, i32), // 关联三个 i32 类型
}
fn main() {
let msg = Message::Write(String::from("Hello Rust"));
match msg {
Message::Quit => println!("退出消息"),
Message::Move { x, y } => println!("移动到:x={}, y={}", x, y),
Message::Write(content) => println!("收到消息:{}", content), // 提取关联的 String 数据
Message::ChangeColor(r, g, b) => println!("切换颜色:R={}, G={}, B={}", r, g, b),
}
}
错误匹配
enum Message {
Quit, // 无关联数据
Move { x: i32, y: i32 }, // 关联匿名结构体
Write(String), // 元组结构体
ChangeColor(i32, i32, i32), // 关元组结构体
}
fn main() {
let msg = Message::Move {
x: 22,
y: 33
};
match msg {
// 错误:字段名 a、b 与定义的 x、y 不一致
Message::Move { a, b } => println!("移动到:a={}, b={}", a, b),
_ => println!("xxx")
}
}
重命名方式
enum Message {
Quit, // 无关联数据
Move { x: i32, y: i32 }, // 关联匿名结构体
Write(String), // 元组结构体
ChangeColor(i32, i32, i32), // 关元组结构体
}
fn main() {
let msg = Message::Move { x: 10, y: 20 };
match msg {
// 字段名 x、y 与定义一致,解构后重命名为 a、b
Message::Move { x: a, y: b } => println!("移动到:a={}, b={}", a, b),
_ => println!("xxx")
}
}
模式绑定
格式:
<绑定变量名> @ <匹配模式>
基础模式绑定
绑定字面量模式
fn main() {
let num = 5;
match num {
// 语法:变量 @ 字面量
n @ 5 => println!("匹配到数字 5,绑定变量 n = {}", n),
m @ 10 => println!("匹配到数字 10,绑定变量 m = {}", m),
_ => println!("匹配到其他数字"),
}
}
绑定范围模式
fn main() {
let score = 95;
match score {
// 语法:变量 @ 范围
excellent @ 90..=100 => println!("优秀,分数:{}", excellent),
good @ 80..=89 => println!("良好,分数:{}", good),
pass @ 60..=79 => println!("及格,分数:{}", pass),
fail @ 0..=59 => println!("不及格,分数:{}", fail),
_ => println!("无效分数"),
}
}
绑定通配符模式
username @ _完全等价于username
fn main() {
let name = String::from("zhangsan");
match name {
// 语法:变量 @ _(匹配任意值,绑定到变量)
username @ _ => println!("用户名:{}", username),
}
}
fn main() {
let name = String::from("zhangsan");
match name {
// 效果和上面一样
username => println!("用户名:{}", username),
}
}
结构体模式绑定
绑定完整结构体模式
ref u:借用整个User结构体的所有权字段
ref name:借用name字段(String类型)的所有权
#[derive(Debug)]
struct User {
id: u64,
name: String,
age: u8,
}
fn main() {
let user = User {
id: 1001,
name: String::from("lisi"),
age: 25,
};
match user {
// 语法:变量 @ 结构体 { 字段1, 字段2, 字段3 }
ref u @ User { id, ref name, age } => {
println!("绑定完整结构体:{:?}", u);
println!("解构字段:id={}, name={}, age={}", id, name, age);
}
}
}
绑定部分结构体模式
实际开发中常无需关注所有字段,用
..忽略无关字段,简化语法。
#[derive(Debug)]
struct User {
id: u64,
name: String,
age: u8,
}
fn main() {
let user = User {
id: 1001,
name: String::from("lisi"),
age: 25,
};
match user {
// 语法:变量 @ 结构体 { 关注字段, .. }
ref u @ User { age, .. } => {
println!("绑定结构体(仅关注年龄):{:?}", u);
println!("用户年龄:{}", age);
}
}
}
绑定嵌套结构体模式
结构体中包含其他结构体,
@支持嵌套绑定,语法层层嵌套即可。
#[derive(Debug)]
struct Address {
city: String,
street: String,
}
#[derive(Debug)]
struct User {
id: u64,
name: String,
address: Address, // 嵌套结构体
}
fn main() {
let user = User {
id: 1001,
name: String::from("lisi"),
address: Address {
city: String::from("Beijing"),
street: String::from("Wangfujing Street"),
},
};
match user {
// 语法:外层变量 @ 外层结构体 { 嵌套字段 @ 嵌套结构体 { .. }, .. }
ref u @ User {
address: ref addr @ Address { ref city, .. },
..
} => {
println!("外层结构体:{:?}", u);
println!("嵌套地址结构体:{:?}", addr);
println!("用户所在城市:{}", city);
}
}
}
枚举模式绑定@
绑定无关联数据的枚举变体
无关联数据的枚举变体,
@绑定的是变体本身(意义不大,更多用于清晰表达意图)
enum Direction {
Up,
Down,
Left,
Right,
}
fn main() {
let dir = Direction::Up;
match dir {
// 语法:变量 @ 枚举变体
d @ Direction::Up => println!("绑定枚举变体:Up(变量 d)"),
d @ Direction::Down => println!("绑定枚举变体:Down(变量 d)"),
_ => println!("其他方向"),
}
}
绑定带关联数据的枚举变体
带关联数据的枚举变体,
@可绑定「整个关联数据」或「部分关联数据」,是核心用法没用
ref的话会获取所有权
enum Message {
Quit,
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msg = Message::Write(String::from("Hello Rust"));
match msg {
// 1. 绑定单个关联数据
// Message::Write(content)效果一样, 移动所有权了
Message::Write(content @ _) => println!("收到消息:{}", content),
// 2. 绑定多个关联数据(部分绑定)
Message::ChangeColor(r @ 0..=255, g @ 0..=255, b @ 0..=255) => {
println!("合法颜色:R={}, G={}, B={}", r, g, b);
}
// 3. 无绑定(仅匹配)
Message::Quit => println!("退出消息"),
_ => println!("其他消息"),
}
}
绑定嵌套枚举模式
如果枚举关联了其他枚举,
@支持嵌套绑定,语法层层拆解即可。
#[derive(Debug)]
enum ResultCode {
Success,
Error(u32),
}
#[derive(Debug)]
enum ApiResponse {
Ok(ResultCode, String),
Failed(String),
}
fn main() {
let resp = ApiResponse::Ok(ResultCode::Success, String::from("数据查询成功"));
match resp {
// 语法:外层变量 @ 外层枚举 { 嵌套变量 @ 嵌套枚举, .. }
ref r @ ApiResponse::Ok(ref code @ ResultCode::Success, ref msg @ _) => {
println!("接口响应:{:?}", r);
println!("code:{:?}", code);
println!("结果码:成功,消息:{}", msg);
}
_ => println!("接口调用失败"),
}
}
带守卫条件的模式绑定
<绑定变量名> @ <匹配模式> if <布尔条件>
fn main() {
let score = 88;
match score {
// 绑定范围,且额外过滤:偶数
good @ 80..=89 if good % 2 == 0 => {
println!("良好,且是偶数分数:{}", good);
}
// 绑定范围,不满足守卫条件的分支
80..=89 => println!("良好,但不是偶数分数"),
_ => (),
}
}
if-let
元组结构体
单元组
#[derive(Debug)]
enum OptionInt {
Some(String),
None,
}
fn main() {
let o = OptionInt::Some(String::from("acdc"));
// 仅关心 Some 分支,忽略 None,用 if let 更简洁
if let OptionInt::Some(n) = o {
println!("文字内容:{}", n);
}
}
多元组
#[derive(Debug)]
enum Message {
Quit,
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let o = Message::ChangeColor(1,2,3);
if let Message::ChangeColor(x,y,z) = o {
println!("x内容:{}", x);
println!("y内容:{}", y);
println!("z内容:{}", z);
}
}
结构体
#[derive(Debug)]
enum Message {
Quit,
Pp{x: String, y: String},
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let o = Message::Pp{
x: String::from("AA"),
y: String::from("BB"),
};
// 仅关心 Some 分支,忽略 None,用 if let 更简洁
if let Message::Pp{x,y} = o {
println!("x内容:{}", x);
println!("y内容:{}", y);
}
}
枚举模式绑定@
struct重命名
需要添加ref,变为借用
#[derive(Debug)]
enum Message {
Quit,
Pp{x: String, y: String},
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let o = Message::Pp{
x: String::from("AA"),
y: String::from("BB"),
};
// 仅关心 Some 分支,忽略 None,用 if let 更简洁
if let ref ppp @ Message::Pp{ref x, ref y} = o {
println!("ppp内容:{:?}", ppp);
println!("x内容:{}", x);
println!("y内容:{}", y);
}
}
字段重命名
#[derive(Debug)]
enum Message {
Quit,
Pp{x: String, y: String},
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let o = Message::Pp{
x: String::from("AA"),
y: String::from("BB"),
};
// 正确写法:1. 字段重命名语法:x: aa(原始字段名: 新变量名) 2. ref 放在新变量名前(或整体前)
if let ref ppp @ Message::Pp{ x: ref aa, y: ref bb } = o {
println!("ppp内容:{:?}", ppp);
println!("aa内容:{}", aa);
println!("bb内容:{}", bb);
}
}

浙公网安备 33010602011771号