[英]What are the Rust borrowing rules regarding mutable internal references?
对我来说,为什么一个类似的程序并不直观
#[derive(Debug)]
struct Test {
buf: [u8; 16],
}
impl Test {
fn new() -> Test {
Test {
buf: [0u8; 16],
}
}
fn hi(&mut self) {
self.buf[0] = 'H' as u8;
self.buf[1] = 'i' as u8;
self.buf[2] = '!' as u8;
self.print();
}
fn print(&self) {
println!("{:?}", self);
}
}
fn main() {
Test::new().hi();
}
编译和运行没有任何问题,但像一个程序
#[derive(Debug)]
enum State {
Testing([u8; 16]),
}
#[derive(Debug)]
struct Test {
state: State,
}
impl Test {
fn new() -> Test {
Test {
state: State::Testing([0u8; 16]),
}
}
fn hi(&mut self) {
match self.state {
State::Testing(ref mut buf) => {
buf[0] = 'H' as u8;
buf[1] = 'i' as u8;
buf[2] = '!' as u8;
self.print();
},
}
}
fn print(&self) {
println!("{:?}", self);
}
}
fn main() {
Test::new().hi();
}
编译过程中的错误,错误
错误[E0502]:不能将
*self
借用为不可变因为self.state.0
也被借用为可变的
由于两个程序基本上都是相同的东西,第二个似乎不会从内存的角度看起来更不安全。 我知道必须要有一些关于我必须缺少的借用和范围规则,但不知道是什么。
为了使你的hi
函数工作,你只需要将print
出match
表达式中引入的可变扩展的范围:
fn hi(&mut self) {
match self.state {
State::Testing(ref mut buf) => {
buf[0] = 'H' as u8;
buf[1] = 'i' as u8;
buf[2] = '!' as u8;
},
}
self.print();
}
由于第二种情况中存在match
块,您的两个变体不相等。 我不知道如何在没有模式匹配的情况下直接访问enum
的元组结构(或者如果现在甚至可能这样),但如果是这样的话,那么实际上没有太大区别,两个版本都可以工作。
在match
语句中,您借用self.state
。 借用范围是词汇,因此它在整个match
块中借用。 当你调用self.print()
,你需要借用self
。 但这是不可能的,因为self
一部分已经被借用了。 如果在match
语句之后移动self.print()
,它将起作用。
关于词汇借用范围,您可以在每个Rust开发人员应该了解的借用检查器中的两个错误的第二部分中阅读更多内容 。 相关问题: #6393 , #811 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.