赞
踩
先定义一个struct:
- #[derive(Debug)]
- struct Point {
- x: Box<i32>,
- y: Box<i32>,
- z: i32,
- }
在前面的学习中提到,struct拥有数据的所有权,并且对于实现了copy的类型,可以直接copy出去,以下代码,是可以正常编译的:
- fn main() {
- let a = Point {
- x: Box::new(3),
- y: Box::new(4),
- z: 5,
- };
- let b = a.z; // copy a.z to b. a is still available.
-
- println!("{:?}", b);
- println!("{:?}", a);
- }
但有意思的来了!我们试试成员x:
- fn main() {
- let a = Point {
- x: Box::new(3),
- y: Box::new(4),
- z: 5,
- };
- let b = a.x;
-
- println!("{:?}", b);
- println!("{:?}", a);
- }
系统则提示如下错误:
borrow of partially moved value: `a`
value borrowed here after partial move
note: partial move occurs because `a.x` has type `std::boxed::Box<i32>`, which does not implement the `Copy`
由于成员x是Box类型,未实现Copy Trait,故在上面的代码中,
let b = a.x;
实际上是将a.x move到了变量b中,a.x不再有效和可用,所以在最后一行要打印a时,系统报错“value borrowed here after partial move”,结构体a的值被部分移动了!要强调的是,a是不可变的(没有mut关键字)!虽然对rust还不够熟悉,但结构体成员的值竟然可以部分被移动(伴随的是移动部分的所有权的转移),感觉这个设计还是蛮奇怪的,也挺有意思的。并且可以移动不同的成员出去,或者说可以同时转移未实现Copy Trait的不同成员的所有权出去,如下代码,可以同时将成员x和y转移出去,是可以编译通过的:
- let a = Point {
- x: Box::new(3),
- y: Box::new(4),
- z: 5,
- };
- let b = a.x;
- let c = a.y;
-
- println!("{:?}", b);
- println!("{:?}", c);
虽然目前还不知道struct这样设计的原因,但这点对于struct的所有权的灵活性是很有帮助的。对于链表的实现,也是非常有用的。下次我们看看在借用情况的所有权问题。
补:
写完本篇之后,又尝试了一个动作:部分移出,部分借用,如下,也是可行的:
let b = a.x;
let c = &a.y;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。