为什么在可变引用上调用方法涉及 "borrowing"?
Why does calling a method on a mutable reference involve "borrowing"?
我正在学习 Rust,我正在尝试将这段代码用于编译:
use std::vec::Vec;
use std::collections::BTreeMap;
struct Occ {
docnum: u64,
weight: f32,
}
struct PostWriter<'a> {
bytes: Vec<u8>,
occurrences: BTreeMap<&'a [u8], Vec<Occ>>,
}
impl<'a> PostWriter<'a> {
fn new() -> PostWriter<'a> {
PostWriter {
bytes: Vec::new(),
occurrences: BTreeMap::new(),
}
}
fn add_occurrence(&'a mut self, term: &[u8], occ: Occ) {
let occurrences = &mut self.occurrences;
match occurrences.get_mut(term) {
Some(x) => x.push(occ),
None => {
// Add the term bytes to the big vector of all terms
let termstart = self.bytes.len();
self.bytes.extend(term);
// Create a new occurrences vector
let occs = vec![occ];
// Take the appended term as a slice to use as a key
// ERROR: cannot borrow `*occurrences` as mutable more than once at a time
occurrences.insert(&self.bytes[termstart..], occs);
}
}
}
}
fn main() {}
我收到一个错误:
error[E0499]: cannot borrow `*occurrences` as mutable more than once at a time
--> src/main.rs:34:17
|
24 | match occurrences.get_mut(term) {
| ----------- first mutable borrow occurs here
...
34 | occurrences.insert(&self.bytes[termstart..], occs);
| ^^^^^^^^^^^ second mutable borrow occurs here
35 | }
36 | }
| - first borrow ends here
我不明白...我只是在可变引用上调用方法,为什么该行会涉及借用?
I'm just calling a method on a mutable reference, why would that line involve borrowing?
当您调用一个对象的方法时,该对象将改变该对象,您不能任何其他未完成的对象引用。如果这样做,您的变更可能会使这些引用无效并使您的程序处于不一致状态。例如,假设您从哈希图中获取了一个值,然后添加了一个新值。添加新值会达到神奇的限制并强制重新分配内存,您的值现在无处可去!当您使用该值时...程序开始运行!
在这种情况下,您似乎想要执行相对常见的 "append or insert if missing" 操作。您将要为此使用 entry
:
use std::collections::BTreeMap;
fn main() {
let mut map = BTreeMap::new();
{
let nicknames = map.entry("joe").or_insert(Vec::new());
nicknames.push("shmoe");
// Using scoping to indicate that we are done with borrowing `nicknames`
// If we didn't, then we couldn't borrow map as
// immutable because we could still change it via `nicknames`
}
println!("{:?}", map)
}
因为您正在调用一个借用为可变的方法
昨天我有一个关于哈希的类似问题,直到我在文档中注意到一些东西。 The docs for BTreeMap 显示 insert
的方法签名,以 fn insert(&mut self..
开头
因此,当您调用 .insert
时,您是在隐含地要求该函数借用 BTreeMap 作为可变对象。
我正在学习 Rust,我正在尝试将这段代码用于编译:
use std::vec::Vec;
use std::collections::BTreeMap;
struct Occ {
docnum: u64,
weight: f32,
}
struct PostWriter<'a> {
bytes: Vec<u8>,
occurrences: BTreeMap<&'a [u8], Vec<Occ>>,
}
impl<'a> PostWriter<'a> {
fn new() -> PostWriter<'a> {
PostWriter {
bytes: Vec::new(),
occurrences: BTreeMap::new(),
}
}
fn add_occurrence(&'a mut self, term: &[u8], occ: Occ) {
let occurrences = &mut self.occurrences;
match occurrences.get_mut(term) {
Some(x) => x.push(occ),
None => {
// Add the term bytes to the big vector of all terms
let termstart = self.bytes.len();
self.bytes.extend(term);
// Create a new occurrences vector
let occs = vec![occ];
// Take the appended term as a slice to use as a key
// ERROR: cannot borrow `*occurrences` as mutable more than once at a time
occurrences.insert(&self.bytes[termstart..], occs);
}
}
}
}
fn main() {}
我收到一个错误:
error[E0499]: cannot borrow `*occurrences` as mutable more than once at a time
--> src/main.rs:34:17
|
24 | match occurrences.get_mut(term) {
| ----------- first mutable borrow occurs here
...
34 | occurrences.insert(&self.bytes[termstart..], occs);
| ^^^^^^^^^^^ second mutable borrow occurs here
35 | }
36 | }
| - first borrow ends here
我不明白...我只是在可变引用上调用方法,为什么该行会涉及借用?
I'm just calling a method on a mutable reference, why would that line involve borrowing?
当您调用一个对象的方法时,该对象将改变该对象,您不能任何其他未完成的对象引用。如果这样做,您的变更可能会使这些引用无效并使您的程序处于不一致状态。例如,假设您从哈希图中获取了一个值,然后添加了一个新值。添加新值会达到神奇的限制并强制重新分配内存,您的值现在无处可去!当您使用该值时...程序开始运行!
在这种情况下,您似乎想要执行相对常见的 "append or insert if missing" 操作。您将要为此使用 entry
:
use std::collections::BTreeMap;
fn main() {
let mut map = BTreeMap::new();
{
let nicknames = map.entry("joe").or_insert(Vec::new());
nicknames.push("shmoe");
// Using scoping to indicate that we are done with borrowing `nicknames`
// If we didn't, then we couldn't borrow map as
// immutable because we could still change it via `nicknames`
}
println!("{:?}", map)
}
因为您正在调用一个借用为可变的方法
昨天我有一个关于哈希的类似问题,直到我在文档中注意到一些东西。 The docs for BTreeMap 显示 insert
的方法签名,以 fn insert(&mut self..
因此,当您调用 .insert
时,您是在隐含地要求该函数借用 BTreeMap 作为可变对象。