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

本文探讨了Rust编程语言中结构体引用类型`&T/&mut T`的match语法,强调在匹配时不引发所有权转移的重要性。通过示例代码解释了如何正确地对结构体内部成员进行模式绑定,特别是当成员不实现Copy trait时,必须使用引用。Rust为方便编码,提供了简化匹配结构体内部成员的语法,即使在不改变所有权的情况下也能实现相同功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文摘自《深入理解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的所有权定义下的一个必然的简化选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

任成珺

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

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

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

打赏作者

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

抵扣说明:

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

余额充值