延长变量的生命周期

Posted

技术标签:

【中文标题】延长变量的生命周期【英文标题】: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()

【问题讨论】:

【参考方案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 只会让事情变得更加冗长。 (我刚刚意识到我在编写迭代器建议时犯了一个错误。正在修复。)

以上是关于延长变量的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

XSS利用之延长Session生命周期

Laravel Passport:延长 Token 的生命周期

为啥我们可以非常量引用临时对象并延长其生命周期?

如何在 Symfony 中延长会话 cookie 的生命周期?

在构造函数之外延长 QT 对象的生命周期

关于延长物联网设备的生命周期