generics - 返回保守的 impl 特征时,一生意味着什么?
问题描述
在搜索有关保守 impl trait的文档时,我发现了这个示例:
struct A {
x: [(u32, u32); 10]
}
impl A {
fn iter_values<'a>(&'a self) -> impl 'a + Iterator<Item = u32> {
self.x.iter().map(|a| a.0)
}
}
'a
返回类型中的生命周期是什么意思?
我知道这个关于生命周期限制的问题Box
,但我认为用例是不同的。如果我理解得很好,答案是:
trait 对象仅在生命周期内有效 'a
这意味着存在于堆中某处的特征对象将持续一生'a
。
但是在这里,这不是一个特征对象,而是一个存在于堆栈中的具体对象。所以编译器不需要提示它的生命周期。
我错过了什么?
解决方案
语法impl Iterator<Item = u32> + 'a
意味着
- 将返回函数定义的某些类型,但您不知道确切的类型。这就是
impl ...
部分。 - 未指定的具体类型将是
u32
值的迭代器。这就是Iterator<Item = u32>
部分。 - 未指定的具体类型可能包含具有生命周期的引用
'a
。这就是+ 'a
部分。
在您的示例中,返回的迭代器包含对 的引用self
,因此不得允许它的寿命超过 的实例A
,否则它将无效。具体类型(如果我们可以写的话)是iter::Map<slice::Iter<'a, (u32, u32)>, <closure>>
——注意它里面有一个'a
。
这意味着存在于堆中某处的特征对象将持续一生
'a
。
这并不完全正确。这两种情况具有相同的含义:未指定的具体类型可能包含引用。对于 trait 对象,具体类型位于某种指针(Box
、&
、Rc
等)的后面。使用 impl trait,具体类型直接放在堆栈上。
这不是特征对象,而是存在于堆栈中的具体对象
特征对象不需要堆;他们只能利用堆栈:
let x: &std::fmt::Display = &42;
println!("{}", x);
也可以看看:
推荐阅读
- css - 使用 Bootstrap 的 flex div 行和列的重叠大小固定块
- php - Laravel DB 一次运行两个查询(SELECT/UPDATE)
- react-native - React Native - flex:1在键盘打开时不适用于ios
- reactjs - 为什么状态不会在 React 组件中重置?
- asp.net - 在 NHibernate 中使用时间戳进行版本控制
- docker - 存储库未在 docker build 中登录
- java - 为什么我需要用 Arrays.asList() 替换 List.of()?
- python - 为什么在exec下的另一个函数中没有定义函数?
- angular - 如何等待外部 observable 发出一个值,然后在订阅另一个 observable 之前检查条件?
- linux - 如何使用 sed 命令更改 limits.conf 中的 ulimit 值?