Rust学习笔记(11)——Option和struct组合带来的所有权问题及总结

在上一篇的基础上,我们加一层Option的包裹。还是先定义struct:

#[derive(Debug)]
struct Point {
    x: Box<i32>,
    y: i32,
}

下列代码不可编译:

fn main() {
    let a = Some(Point {
        x: Box::new(5),
        y: 5,
    });
    let b = a.as_ref();
    let c = b.unwrap();
    let d = *c; // Error! move occurs because `*c` has type `Point`, which does not implement the `Copy` trait

    println!("c = {:?}", c);
    println!("b = {:?}", b);
    println!("a = {:?}", a);
}

变量b为a调用as_ref()后获得的新Option,类型为Option<&Point>; c 为b unwrap后的值,类型为&Point,d尝试对c进行解引用,违反了所有权规则,编译错误。

如果修改为as_mut(), 会报类似的错误,如下,原因也类似:

    let mut a = Some(Point {
        x: Box::new(5),
        y: 5,
    });
    let b = a.as_mut();
    let c = b.unwrap();
    let d = *c; // Error! move occurs because `*c` has type `Point`, which does not implement the `Copy` trait

直接使用获得的引用或可变引用,是可以的:

fn main() {
    let mut a = Some(Point {
        x: Box::new(5),
        y: 5,
    });
    let b = a.as_mut();
    let c = b.unwrap();
    c.x = Box::new(10);

    println!("c = {:?}", c);
    // println!("b = {:?}", b);
    println!("a = {:?}", a);
}

上述代码对c.x的改变,直接改变了a的值,输出如下:

c = Point { x: 10, y: 5 }
a = Some(Point { x: 10, y: 5 })

或:

fn main() {
    let mut a = Some(Point {
        x: Box::new(5),
        y: 5,
    });
    let b = a.as_mut();
    let c = b.unwrap();
    // c.x = Box::new(10);
    *c.x += 10;

    // or 
    // let d = &mut c.x;
    // **d += 10;

    println!("c = {:?}", c);
    // println!("b = {:?}", b);
    println!("a = {:?}", a);
}

输出:

c = Point { x: 15, y: 5 }
a = Some(Point { x: 15, y: 5 })

最后,对于之前几篇学习的几个主要结论总结一下:

  1. 对于struct类型,如果成员未实现Copy trait,可以将其部分或全部成员的所有权转移出去;
  2. struct类型的(可变)引用,无法转移成员的所有权;(别小看这个,这是不同于C/C++编写链表时的坑之一)
  3. struct类型的(可变)引用,不能解引用;其成员的(可变)引用,如果成员未实现Copy trait,也不能解引用;(参考笔记(10)
  4. Option类型可以通过unwrap、take 分别获取包含对象的值的所有权,通过as_ref/as_mut获取包含对象的引用或可变引用;
  5. 对引用可以继续引用,可变引用类似。这类似于C语言中的指针的指针;(笔记(8)中有实验
  6. struct支持分别对其不同成员同时进行可变引用,Vec则不支持。(笔记(6)中有实验
  7. 不可变引用不能改变其指向变量的值,其本身(指针本身)可以通过copy进行复制;(笔记(6)中有实验​​​​​​​)
  8. 可变引用可以改变指向变量的值,可变引用这个变量本身(指针本身)未实现Copy trait,其赋值是move 操作。(笔记(6)中有实验​​​​​​​)

暂时到这里吧,以后如果有新的发现再补充。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值