[英]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.