gpt4 book ai didi

rust - 我可以使用借来的元素对向量进行变异吗?

转载 作者:行者123 更新时间:2023-12-03 11:38:06 24 4
gpt4 key购买 nike

我正在尝试存储对可变向量元素的引用,以供以后使用。但是,一旦对向量进行了变异,就无法再使用存储的引用。我知道这是因为借用对元素的引用也需要借用对向量本身的引用。因此,无法修改向量,因为这将需要借用可变引用,而当已经借用了对该向量的另一引用时,则不允许这样做。
这是一个简单的例子

struct Person {
name: String,
}

fn main() {
// Create a mutable vector
let mut people: Vec<Person> = ["Joe", "Shavawn", "Katie"]
.iter()
.map(|&s| Person {
name: s.to_string(),
})
.collect();

// Borrow a reference to an element
let person_ref = &people[0];

// Mutate the vector
let new_person = Person {
name: "Tim".to_string(),
};
people.push(new_person);

// Attempt to use the borrowed reference
assert!(person_ref.name == "Joe");
}
产生以下错误
error[E0502]: cannot borrow `people` as mutable because it is also borrowed as immutable
--> src/main.rs:21:5
|
15 | let person_ref = &people[0];
| ------ immutable borrow occurs here
...
21 | people.push(new_person);
| ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
24 | assert!(person_ref.name == "Joe");
| --------------- immutable borrow later used here
我也尝试将矢量元素装箱为建议的 here,但这无济于事。我认为这可能允许我在保持对元素的引用的同时删除对向量的引用,但显然不是。
struct Person {
name: String,
}

fn main() {
// Create a mutable vector
let mut people: Vec<Box<Person>> = ["Joe", "Shavawn", "Katie"]
.iter()
.map(|&s| {
Box::new(Person {
name: s.to_string(),
})
})
.collect();

// Borrow a reference to an element
let person_ref = people[0].as_ref();

// Mutate the vector
let new_person = Box::new(Person {
name: "Tim".to_string(),
});
people.push(new_person);

// Attempt to use the borrowed reference
assert!(person_ref.name == "Joe");
}
这仍然会产生相同的错误
error[E0502]: cannot borrow `people` as mutable because it is also borrowed as immutable
--> src/main.rs:23:5
|
17 | let person_ref = people[0].as_ref();
| ------ immutable borrow occurs here
...
23 | people.push(new_person);
| ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
26 | assert!(person_ref.name == "Joe");
| --------------- immutable borrow later used here
有没有办法做到这一点,或者我是否正在尝试做一些不可能的事情?

最佳答案

我发现使用reference counted smart pointer可以完成我的尝试。共享所有权是必要的,这是有道理的,因为否则,如果原始向量超出范围,则元素引用将变得无效(这会在有或没有Box的情况下取消分配元素)。
以下代码成功编译。

use std::rc::Rc;

struct Person {
name: String,
}

fn main() {
// Create a mutable vector
let mut people: Vec<Rc<Person>> = ["Joe", "Shavawn", "Katie"]
.iter()
.map(|&s| {
Rc::new(Person {
name: s.to_string(),
})
})
.collect();

// Borrow a reference to an element
let person_ref = Rc::clone(&people[0]);

// Mutate the vector
let new_person = Rc::new(Person {
name: "Tim".to_string(),
});
people.push(new_person);

// Attempt to use the borrowed reference
assert!(person_ref.name == "Joe");
}
如果其他人有任何更正,改进或更多的见识,我将很高兴听到。但是,如果没有,我现在对此答案感到满意。

关于rust - 我可以使用借来的元素对向量进行变异吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66219238/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com