【问题标题】:Extend lifetime of variable延长变量的生命周期
【发布时间】:2015-05-03 10:53:11
【问题描述】:

我正在尝试从我的函数内部构建的向量返回一个切片。显然这不起作用,因为v 的生命周期过早到期。我想知道是否有办法延长v 的生命周期。我想返回一个普通的切片,而不是一个向量。

pub fn find<'a>(&'a self, name: &str) -> &'a[&'a Element] {
    let v: Vec<&'a Element> = self.iter_elements().filter(|&elem| elem.name.borrow().local_name == name).collect();
    v.as_slice()
}

【问题讨论】:

    标签: rust lifetime


    【解决方案1】:

    你不能强行延长一个值的生命周期;您只需返回完整的Vec。如果我可能会问,您为什么要返回切片本身?这几乎总是没有必要的,因为 Vec 可以很便宜地(在语法简单和运行时开销低的意义上)强制转换为切片。

    或者,您可以返回迭代器:

    use std::iter;
    
    pub fn find<'a>(&'a self, name: &str) -> Box<Iterator<Item = &'a Element> + 'a> {
        Box::new(self.iter_elements()
           .filter(move |&elem| elem.name.borrow().local_name == name))
    }
    

    现在,您将不得不使用迭代器特征对象,因为闭包具有不可命名的类型。

    注意。我必须将 filter 闭包更改为 capture-by-move(move 关键字)以确保它可以被返回,否则 name 变量只会传递到闭包指针到 find's堆栈帧,因此将被限制离开find

    【讨论】:

    • 我想返回一个只读列表。我想我需要的是 OwnedSlice,但这可能只是 Vec。我不能返回一个迭代器,因为我希望它是可索引的。
    • 由于Vec(或其他)包含&amp;Elements,因此列表的实际内容与&amp;[] 一样是只读的。返回Vec 而不是&amp;[] 实际上只允许用户修改该向量的长度(例如push/pop 元素),限制通常是不必要的,尤其是在Rust 中,其中Vec s 等是唯一拥有的,因此更改 Vec 不会更改其他任何地方的任何值。
    • 另外,您可以返回一个迭代器:如果用户绝对需要多次随机访问它,那么他们可以手动.collect()。如果他们只想按顺序迭代,或者随机索引一次(可能通过nth),那么返回迭代器可能会更有效,因为元素只会按需生成。当然,如果结构通常是随机访问的,那么要求collect 只会让事情变得更加冗长。 (我刚刚意识到我在编写迭代器建议时犯了一个错误。正在修复。)
    猜你喜欢
    • 2015-07-31
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多