Rust 中具有 R 和 O 权限的引用如何读取或移动?
数据阿明
结论
可以解引用共享引用来读取它指向的数据,例如 *num。引用本身也是一个值。&i32 这样的共享引用实现了 Copy,赋值给另一个变量时会复制引用值,不会移动它指向的数据。
如何读取数据
代码中的 num 类型是 &i32,也就是指向 i32 的共享引用。使用 *num 解引用,可以取得被引用的整数值:
let num: &i32 = &v[2];
println!("Third element is {}", *num);
也可以直接用 num 调用需要 i32 的格式化输出,因为 println! 的格式化机制会处理这个参数。写出 *num 则能更清楚地表明,读取的是引用指向的整数。
共享引用只允许读取数据,不能通过它修改数据。要通过引用修改数据,需要使用可变引用 &mut T,并遵守 Rust 的可变借用规则。
如何移动或复制引用
&i32 是可复制的共享引用。下面的赋值会复制引用值,不会移动或复制整数本身:
let num: &i32 = &v[2];
let another = num;
println!("{} {}", *num, *another);
num 和 another 指向同一个整数。对不可复制的值赋值时,通常会发生所有权移动。可变引用 &mut T 不实现 Copy,赋值时会移动引用值,同时受独占可变借用规则限制。
R 和 O 应如何理解
R、W、O 是权限模型中的概念。理解这段示例时,需要区分引用值 num 和它指向的 v[2]:读取权限说明是否可以读取数据;如果拥有权限适用于引用变量,它说明的是能否移动或丢弃引用值,并不代表拥有或移动被引用的整数。共享引用可以读取数据,但不能通过它写入数据。
println! 用完 num 后,代码不再使用这个引用,因此借用可以在此处结束。之后,v.push(4) 可以对向量进行可变操作。如果 push 之后还要使用 num,借用就可能与对向量的修改冲突,因为修改 Vec 可能导致元素位置变化。
备注:内容仅供参考。
