标签:活动 编译错误 不能 src new 方法 gate 另一个 rms
新手眼中的 Rust 所有权规则如果你有关注本人博客,那么很明显,从今年年初开始,我便开始学习 Rust。此文与之前风格略有不同,旨在总结阅读 Rust 书籍时遇到的要点。到目前为止,它包含了我对 Rust 所有权规则的所有理解。
Rust 的主要亮点之一是它提供了内存安全性。通过提供编译时保证,将可能会导致内存错误的标志代码标记为编译时错误来做到这一点。编译时保证是通过所有权规则来实现。在这篇文章中,我总结了 Rust 所有权规则关键点,简述如下:
变量的值可以被其他变量使用有 4 种方法,需要遵循的规则如下:
为了确保上述所有用法都不会造成内存错误,Rust 在编译时强制执行其所有权规则,概述如下:
对值进行克隆没有什么特别,如果你已经编程了一段时间,并且知道如何传递数字和字符串之类的变量,则几乎与你习惯的机制相同。因此,实际上没有多少 Rust 特定的规则可以在这里强调。大多数情况下,你不需要克隆值,因为成本比较高。变量的其他用法与 Rust 特定的规则一起提供,因此我们将对其进行详细介绍。
随着所有权 move,保存该值的原始变量将不再可用。现在只能通过新的变量访问该值。尝试使用已 move 所有权的变量,将导致编译错误:
fn main() {
let mut original_owner = format!("Hello world");
// move occurs to new owner
let new_owner = original_owner;
// attempt to use original_owner will
// lead to compile time error
println!("{}", original_owner)
}
error[E0382]: borrow of moved value: `original_owner`
使用不可变借用,借用的变量可以读取该值,但不能修改(即使原始值是 mutable 类型)不可变借用保证借用变量的值不会修改。任何试图违反这些条件的代码都将导致编译错误。
由于尝试修改不可变借用导致的编译错误
fn main() {
let mut original_owner = format!("Hello world");
// immutable borrow occurred
let borrow_owner = &original_owner;
// multiple reads possibe via owner
println!("{}", original_owner);
println!("{}", original_owner);
// multiple reads possible via borrower
println!("{}", borrow_owner);
println!("{}", borrow_owner);
//error: mutating not possible via borrower
borrow_owner.push(‘.‘)
}
error[E0596]: cannot borrow `*borrow_owner` as mutable, as it is behind a `&` reference
--> src/main.rs:14:5
如果违反不可变借用变量不能修改的约束,Rust 编译器会在编译时报错。
fn main() {
let mut original_owner = format!("Hello world");
// immutable borrow occurred
let borrow_owner = &original_owner;
// multiple reads possible via owner
println!("{}", original_owner);
println!("{}", original_owner);
// multiple reads possible via borrower
println!("{}", borrow_owner);
// original owner trying to mutate
original_owner.push(‘.‘);
println!("{}", borrow_owner);
}
error[E0502]: cannot borrow `original_owner` as mutable because it is also borrowed as immutable
如果将变量修改移到借用方超出范围的位置,则该修改不会导致编译错误。这是因为不存在违反对不可变借用的担保(即值不会改变)。例如以下编译:
fn main() {
let mut original_owner = format!("Hello world");
// immutable borrow occurred
let borrow_owner = &original_owner;
// multiple reads possible via owner
println!("{}", original_owner);
println!("{}", original_owner);
// multiple reads possible via borrower
println!("{}", borrow_owner);
println!("{}", borrow_owner);
// original owner trying to mutate
original_owner.push(‘.‘);
}
使用可变借用,借用方将获得该变量的所有权,这意味着新的读写必须经过借用方。具有可变所有权的原始变量也将无法读取或写入,直到可变借用方超出使用范围。该限制强制执行内存一致性。由于它有效地不允许通过除变量之外的其他方式进行任何其他写入或读取,因此它可以避免出现数据数据争用之类的情况。
可变借用的规则还确保始终只有一个活动的可变借用。这样做的道理在于,一旦你拥有多个可变借用并且具有修改的能力,就无法保持数据一致性。这些规则在编译时进行检查。
多次使用可变借用导致编译错误
fn main() {
let mut original_owner = format!("Hello world");
// mutable borrow occurred
let borrow_mutable_owner = &mut original_owner;
// compile error due to second mutable borrow
let illegal_borrow = &mut original_owner;
println!("{}", borrow_mutable_owner);
}
error[E0499]: cannot borrow `original_owner` as mutable more than once at a time
下面是违反了可变借用独占访问的编译错误
fn main() {
let mut original_owner = format!("Hello world");
// mutable borrow occurred
let borrow_mutable_owner = &mut original_owner;
// borrowing owner can also mutate
borrow_mutable_owner.push(‘!‘);
// compile error due to:
//original owner can no longer read
println!("{}", original_owner);
// compile error due to:
// original owner also cannot write
original_owner.push(‘.‘);
println!("{}", original_owner);
println!("{}", borrow_mutable_owner);
println!("{}", borrow_mutable_owner);
}
error[E0502]: cannot borrow `original_owner` as immutable because it is also borrowed as mutable
如果将读取及修改操作移动到可变借用变量超出范围之后,则不会有编译错误。这很好,因为不再需要执行可变借用所要求的互斥。
fn main() {
let mut original_owner = format!("Hello world");
// mutable borrow occurred
let borrow_mutable_owner = &mut original_owner;
// borrowing owner can also mutate
// below is the last usage
borrow_mutable_owner.push(‘!‘);
println!("{}", borrow_mutable_owner);
// borrow_mutable_owner is now out of scope
// original owner can now read
println!("{}", original_owner);
// original owner can now write
original_owner.push(‘.‘);
println!("{}", original_owner);
}
编译以上代码片段,将不会发生任何错误。
简洁地总结一下:
原文:
https://www.geekabyte.io/2020/02/rust-ownership-rules.html
参考阅读:
本文作者 dade,由高可用架构翻译。技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。
标签:活动 编译错误 不能 src new 方法 gate 另一个 rms
原文地址:https://blog.51cto.com/14977574/2546280