echotpq
V2EX  ›  问与答

rust 小白,求教所有权报错

By echotpq at 2021 年 9 月 9 日 · 2048 次点击

rust 小白,求教

1 、合法不会报错 fn main() {

let mut s = String::from("hello");

let r1 = &mut s;

let r2 = r1;

println!("{}",r2);

println!("{}",s);

}

2 、报错,提示 mutable & immutable 错误

fn main() {

let mut s = String::from("hello");

let r1 = &mut s;

let r2 = r1;

println!("{}",s);

println!("{}",r2);

}

两者有什么区别,请高手指教一下

5 条回复  •  2021-09-09 17:10:05 +08:00
misdake
   1
misdake  
   2021 年 9 月 9 日
1 里面,r2 在 println 之后就还回去了,所以 s 可以接着用
2 里面,打印 s 的时候,r2 还借着 s 的 mut 引用,所以不能访问 s
echotpq
   2
echotpq  
OP
   2021 年 9 月 9 日
可是 1 里面 r2 在 println 一次之后,还能继续 println 一次 ,比如 println!("{}",r2); println!("{}",r2); println!("{}",s);
不是 println 一次之后就还回去了吗?怎么还能继续 println 呢?@misdake
XiaoxiaoPu
   3
XiaoxiaoPu  
   2021 年 9 月 9 日   ❤️ 1
kaisery.github.io/trpl-zh-cn/ch04-02-references-and-borrowing.html
注意一个引用的作用域从声明的地方开始一直持续到最后一次使用为止。

1 里面,r2 的最后一次使用在第 5 行,后面就不在 r2 的作用域了
2 里面,r2 的最后一次使用在第 6 行,第 5 行的时候 r2 还是有效的
echotpq
   4
echotpq  
OP
   2021 年 9 月 9 日
@XiaoxiaoPu 谢谢,明白了
ke1e
   5
ke1e  
   2021 年 9 月 9 日
个人理解:

首先,引用是否有效,取决于它引用的对象是否有效;

在 1 中:r2 是 s 的可变引用,s 在 println!("{}",s); 后被清除失效,所以'a (从 s 被定义到 println 之间)都是存活有效的,rust 的引用检查器自然会认为在'a 中,r2 的引用是有效的。这样你在'a 中调用 println!("{}",r2);都是合法的;

在 2 中:同样道理,println!("{}",r2); 在 'a 之外被调用,此时 s 已经被清除,它的引用也都是失效的,所以不合法
© 2026 V2EX · 30ms · 3.9.8.5