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

标签 reference rust lifetime

我在一个对象中有 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/

相关文章:

asp.net - 类型或命名空间名称 'AspNet' 在命名空间 'Microsoft' 中不存在错误?

rust - 为什么不能在同一结构中存储值和对该值的引用?

c# - 对于在控制台应用程序中使用 Microsoft.Web.Administration,是否需要任何额外的引用资料?

rust - 如何将 -mwindows 传递给 cargo build

string - 如何在知道需要多大之前分配一个字符串

iterator - 如何从 &mut 迭代器中提取值?

rust - 变量在嵌套 lambda 中存活时间不够长的借用检查错误

c# - .NET 项目引用 : How to reference a dll via a referenced project?

rust - Rust溢出时带边界的整数运算

random - 为什么这个 rand use 语句在 rust 中起作用?