条件判断

条件判断

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 })时,字段名 xy 必须和枚举定义时的字段名完全一致;

而对于元组形式的关联数据(如 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);
    }
}
posted @ 2026-01-30 00:46  lxd670  阅读(2)  评论(0)    收藏  举报