如何在关联类型中使用非'static trait对象?
问题:为Wrap实现Index trait并返回trait对象引用
我定义了这样一个结构体:
struct Wrap<T>(Vec<T>);
我想要为它实现std::ops::Index trait,让索引操作返回Display trait对象的引用。这是我的首次尝试:
use std::ops::Index; use std::fmt::Display; impl<T> Index<usize> for Wrap<T> where T: Display, { type Output = Display; fn index(&self, index: usize) -> &Self::Output { &self.0[index] } }
可惜这段代码无法编译,报错如下:
error[E0310]: the parameter type `T` may not live long enough --> src/main.rs:13:9 | 7 | impl<T> Index<usize> for Wrap<T> | - help: consider adding an explicit lifetime bound `T: 'static`... ... 13 | &self.0[index] | ^^^^^^^^^^^^^^ | note: ...so that the type `T` will meet its required lifetime bounds --> src/main.rs:13:9 | 13 | &self.0[index] | ^^^^^^^^^^^^^^
我大概明白报错的原因:type Output = Display其实等价于type Output = Display + 'static,因为所有trait对象都隐含生命周期约束,默认就是'static。
我可以给泛型参数T加上'static约束来解决编译错误,但这样会过度限制Wrap能容纳的类型。而且如果不使用关联类型,我可以很轻松地实现类似的功能:
impl<T> Wrap<T> where T: Display, { fn my_index(&self, index: usize) -> &Display { &self.0[index] } }
这段代码不需要'static约束,因为它的签名会被自动解析为:
fn my_index<'a>(&'a self, index: usize) -> &'a (Display + 'a)
这种约束是合理的:trait对象的生命周期至少要和引用self的生命周期'a保持一致。
**但我能不能通过关联类型(也就是实现Index trait)来实现这个功能?**我感觉泛型关联类型(GATs)可能是可行的方向,但一来我不确定具体怎么实现,二来这个特性目前还没有稳定下来。
内容的提问来源于stack exchange,提问作者Lukas Kalbertodt
相关产品推荐
相关产品推荐

