延长变量的生命周期
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
(或其他)包含&Elements
,因此列表的实际内容与&[]
一样是只读的。返回Vec
而不是&[]
实际上只允许用户修改该向量的长度(例如push
/pop
元素),限制通常是不必要的,尤其是在Rust 中,其中Vec
s 等是唯一拥有的,因此更改 Vec
不会更改其他任何地方的任何值。
另外,您可以返回一个迭代器:如果用户绝对需要多次随机访问它,那么他们可以手动.collect()
。如果他们只想按顺序迭代,或者随机索引一次(可能通过nth
),那么返回迭代器可能会更有效,因为元素只会按需生成。当然,如果结构通常是随机访问的,那么要求collect
只会让事情变得更加冗长。 (我刚刚意识到我在编写迭代器建议时犯了一个错误。正在修复。)以上是关于延长变量的生命周期的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Passport:延长 Token 的生命周期