我正在学习 Rust by Example 并运行来自 the "Alias" page 的代码:
struct Point {
x: i32,
y: i32,
z: i32,
}
fn main() {
let mut point = Point { x: 0, y: 0, z: 0 };
{
let borrowed_point = &point;
let another_borrow = &point;
// Data can be accessed via the references and the original owner
println!(
"Point has coordinates: ({}, {}, {})",
borrowed_point.x, another_borrow.y, point.z
);
// Error! Can't borrow point as mutable because it's currently
// borrowed as immutable.
let mutable_borrow = &mut point;
println!(
"Point has coordinates: ({}, {}, {})",
mutable_borrow.x, mutable_borrow.y, mutable_borrow.z
);
let mutable_borrow2 = &mut point;
println!(
"Point has coordinates: ({}, {}, {})",
mutable_borrow2.x, mutable_borrow2.y, mutable_borrow2.z
);
// TODO ^ Try uncommenting this line
// Immutable references go out of scope
}
{
let mutable_borrow = &mut point;
// Change data via mutable reference
mutable_borrow.x = 5;
mutable_borrow.y = 2;
mutable_borrow.z = 1;
// Error! Can't borrow `point` as immutable because it's currently
// borrowed as mutable.
//let y = &point.y;
// TODO ^ Try uncommenting this line
// Error! Can't print because `println!` takes an immutable reference.
//println!("Point Z coordinate is {}", point.z);
// TODO ^ Try uncommenting this line
// Ok! Mutable references can be passed as immutable to `println!`
println!(
"Point has coordinates: ({}, {}, {})",
mutable_borrow.x, mutable_borrow.y, mutable_borrow.z
);
// Mutable reference goes out of scope
}
// Immutable references to point are allowed again
let borrowed_point = &point;
println!(
"Point now has coordinates: ({}, {}, {})",
borrowed_point.x, borrowed_point.y, borrowed_point.z
);
}
在使用最新的 Rust 编译器夜间构建的 Windows 上运行此代码时,我没有遇到编译错误(rustc 1.31.0-nightly (f99911a4a 2018-10-23)
)。 Rust Playground 中最新的每晚构建的 Rust 编译器确实提供了预期的编译错误。
这是为什么?为什么 Rust 编译器可以打破借用规则?我如何在本地修复此问题以获得预期的错误?
最佳答案
当您使用 Rust 1.31 创建一个新的 Cargo 项目时,您会自动选择加入 Rust 2018 版:
[package]
name = "example"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"
这会打开 non-lexical lifetimes ,它启用了一种更智能的借用检查器形式。如果你想要旧的行为,你可以切换回 2015
;这将导致您的代码产生预期的错误。不过,我鼓励您继续使用 2018 版。
Rust Playground 提供版本之间的切换:
Playground 目前默认为 2015 版,在 Rust 1.31 稳定后,Playground 将默认更改为 2018 版。
How I can change this example to provide expected behavior
在 Rust 2018 中你不能。在非词法生命周期之前,Rust 编译器不够智能。代码本身是安全的,但编译器看不到这一点。编译器现在很聪明,所以代码可以编译。没有理由让编译器模式使本质上正确的代码无法编译。
您应该向 Rust by Example 提出问题,让他们知道他们的示例在 Rust 2018 中不再有效。
关于rust - 为什么 Rust 编译器在使用 Rust 1.31 时可以打破借用规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53045978/