RUST中match语法的一个疑难点解析

本文摘自《深入理解RUST标准库》,即将发售,敬请期待

对结构体引用类型“&T/&mut T"的match语法研究

如下代码:

#[derive(Debug)]
struct TestStructA {a:i32, b:i32}
fn main() {
    let c = TestStructA{a:1, b:2};

    match (&c) {
        &e => println!("{:?}", e),
        _  => println!("match nothing"),
    }
}

以上代码编译时,会发生如下错误:

error[E0507]: cannot move out of a shared reference
  --> src/main.rs:9:7
   |
9  | match (&c) {
   |       ^^^^
10 |     &e => println!("{:?}", e),
   |     --
   |     ||
   |     |data moved here
   |     |move occurs because `e` has type `TestStructA`, which does not implement the `Copy` trait
   |     help: consider removing the `&`: `e`

可见,如果match 引用类型,那对后继的pattern绑定是有讲究的。对引用做match,本意便是不想要转移所有权。因此,在match的分支中就不能有引发所有权移动的绑定出现。

再请参考如下代码:

struct TestStructA {a:i32,b:i32}
fn main() {
    let a = 3;
    let b = 1 + 2;
    let c = TestStructA{a:1, b:2};

    match (&c) {
        //u实际绑定为&c.a, w实际绑定为&c.b
        &TestStructA{a:ref u, b:ref w} => println!("{} {}", *u, *w),
        _  => println!("match nothing"),
    }
}

如果不想转移所有权,那上面代码的match就应该是一个标准的写法,对结构内部的变量也需要用ref 引用语法来绑定,尤其是结构内部变量如果没有实现Copy Trait,那就必须用引用,否则也会引发编译告警。

为了编码上的方便,RUST针对以上的代码,支持如下简化形式:


struct TestStructA {a:i32,b:i32}
fn main() {
    let a = 3;
    let b = 1 + 2;
    let c = TestStructA{a:1, b:2};

    match (&c) {
        //对比上述代码,头部少了&,模式绑定内部少了 ref,但代码功能完全一致
        TestStructA{a: u, b: w} => println!("{} {}", *u, *w),
        _  => println!("match nothing"),
    }
}

如果不知道RUST的这个实现,很可能会对这里的类型绑定感到疑惑。但从实际的使用场景分析,对结构体引用做match,其目的就是对结构体内部的成员的引用做pattern绑定。因为如果结构体内部的成员不支持Copy,是不可能对结构体成员做pattern绑定的。所以,此语法也是在RUST的所有权定义下的一个必然的简化选择。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Rust ,`match` 是一个强大的模式匹配表达式,用于处理多个可能的情况。 `match` 表达式由多个分支组成,每个分支包含一个模式和相应的代码块。当 `match` 表达式执行时,它会将待匹配的值与每个分支的模式进行比较,然后执行与匹配成功的分支相关联的代码块。 下面是一个示例,展示了如何使用 `match` 表达式: ```rust fn main() { let number = 5; match number { 1 => println!("One"), 2 => println!("Two"), 3 => println!("Three"), _ => println!("Other"), // `_` 是一个通配符,用于匹配所有其他情况 } } ``` 在这个示例,我们使用 `match` 表达式来匹配 `number` 变量的值。根据匹配的结果,对应的代码块将会被执行。如果没有任何模式匹配成功,那么 `_` 分支将会被执行。 除了字面量模式(如上述示例的数字),`match` 还支持其他类型的模式,如变量模式、通配符模式、引用模式等。你还可以使用 `|` 运算符来匹配多个模式。 下面是一个更复杂的示例,展示了如何使用 `match` 匹配不同的类型: ```rust fn main() { let value: Result<i32, &str> = Ok(10); match value { Ok(number) => println!("Success: {}", number), Err(message) => println!("Error: {}", message), } } ``` 在这个示例,我们使用 `match` 来匹配 `value` 变量的类型。如果 `value` 是 `Ok` 枚举的实例,那么与 `Ok(number)` 匹配的代码块将会被执行。如果 `value` 是 `Err` 枚举的实例,那么与 `Err(message)` 匹配的代码块将会被执行。 通过使用 `match` 表达式,你可以根据不同的模式来处理不同的情况,使代码更加清晰和可读。你可以在 Rust 官方文档了解更多关于 `match` 的详细信息和示例:https://doc.rust-lang.org/reference/expressions/match-expr.html

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

任成珺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值