gpt4 book ai didi

reference - 如何制作引用文献的副本? (生活问题)

转载 作者:行者123 更新时间:2023-11-29 08:08:57 26 4
gpt4 key购买 nike

我在一个对象中有 2 个向量(属于 Result)。第一个向量 all_results 拥有其内容,第二个向量 current_results 包含引用all_results 的内容。这是代码

struct Result {
val: int
}

struct Obj<'a> {
all_results: Vec<Result>,
current_results: Vec<&'a mut Result>
}

impl<'a> Obj<'a> {
fn change_something (&'a mut self) -> &[&'a mut Result] {
let mut newVec: Vec<&'a mut Result> = Vec::new();
for item in self.current_results.mut_iter() {
// type of item is &mut &'a mut Result
item.val += 1;
//need to create valid reference here
if (item.val == 1) {
newVec.push(*item); //dereferenced item is now &'a mut Result
}
}
self.current_results = newVec;
self.current_results.as_slice()
}
}

fn main () {
let a = Result { val: 0 };
let b = Result { val: 1 };
let mut obj = Obj { all_results: vec![], current_results: vec![] };
obj.all_results.push(a);
obj.all_results.push(b);
obj.change_something();
}

基本上,我要做的是遍历 current_results 中的每个条目,修改它们指向的 Result,然后根据某些条件过滤条目。但是,我无法使用相同的引用,因为编译器提示 item 的生命周期超过其范围允许的时间。

iter_lifetime2.rs:16:29: 16:34 error: lifetime of `item` is too short to guarantee its contents can be safely reborrowed
iter_lifetime2.rs:16 newVec.push(*item);
^~~~~
iter_lifetime2.rs:11:61: 21:6 note: `item` would have to be valid for the lifetime 'a as defined on the block at 11:60...
iter_lifetime2.rs:11 fn change_something (&'a mut self) -> &[&'a mut Result] {
iter_lifetime2.rs:12 let mut newVec: Vec<&'a mut Result> = Vec::new();
iter_lifetime2.rs:13 for item in self.current_results.mut_iter() {
iter_lifetime2.rs:14 item.val += 1;
iter_lifetime2.rs:15 if (item.val == 1) {
iter_lifetime2.rs:16 newVec.push(*item);
...
iter_lifetime2.rs:13:9: 19:13 note: ...but `item` is only valid for the expression at 13:8
iter_lifetime2.rs:13 for item in self.current_results.mut_iter() {
iter_lifetime2.rs:14 item.val += 1;
iter_lifetime2.rs:15 if (item.val == 1) {
iter_lifetime2.rs:16 newVec.push(*item);
iter_lifetime2.rs:17 }
iter_lifetime2.rs:18 }

我尝试了几种变体,例如:

for item in self.current_results.mut_iter() {
let p: &'a mut Result = *item;
item.val += 1;
if (item.val == 1) {
newVec.push(p);
}
}

但是关于 item

的生命周期,我得到了同样的错误

这是我的向量的基本指针图,希望它能让我的意图更清楚。谢谢!

pointer diagram

问题:

有没有办法从现有引用中创建引用?感觉我应该能够制作另一个 'a 生命周期的指针,并使其指向 'a 生命周期的对象。或者是否有更好的方法来解决此类问题?

最佳答案

Vec 有一个 retain 方法,几乎​​可以满足您的需求。但是,它不允许在过滤元素之前对元素进行突变。我们可以编写自己的 retain_mut 方法。我刚刚从不可变版本复制代码并修改它以允许突变。

trait RetainMut<T> {
fn retain_mut(&mut self, f: |&mut T| -> bool);
}

impl<T> RetainMut<T> for Vec<T> {
fn retain_mut(&mut self, f: |&mut T| -> bool) {
let len = self.len();
let mut del = 0u;
{
let v = self.as_mut_slice();
for i in range(0u, len) {
if !f(&mut v[i]) {
del += 1;
} else if del > 0 {
v.swap(i-del, i);
}
}
}
if del > 0 {
self.truncate(len - del);
}
}
}

然后你的代码看起来像这样

struct Result {
val: int
}

struct Obj<'a> {
all_results: Vec<Result>,
current_results: Vec<&'a mut Result>
}

impl<'a> Obj<'a> {
fn change_something (&mut self) -> &[&mut Result] {
self.current_results.retain_mut(|result| {
result.val += 1;
result.val == 1
});
self.current_results.as_slice()
}
}

关于reference - 如何制作引用文献的副本? (生活问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25619647/

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