实现Deref的Rust结构体能否返回外部数据的引用?
如何正确实现Rust中Idx结构体的Deref以引用外部数据
我定义了Idx<'a>结构体,它持有&'a Foo和一个索引,逻辑上是对Foo内部数据的引用,且Foo的生命周期长于Idx。我希望让Idx实现Deref trait,使其能解引用到Foo包含的内容,但编写的代码无法通过编译:
use std::ops::Deref; struct Foo { xs: Vec<u8>, } struct Idx<'a>(&'a Foo, usize); impl<'a> Deref for Idx<'a> { type Target = u8; fn deref(&self) -> &u8 { &self.0.xs[self.1] } } fn main() { let foo = Foo { xs: vec!(10, 11, 12), }; let mut xs_refs: Vec<&u8> = vec!(); for i in 0..3 { let idx = Idx(&foo, i); xs_refs.push(&*idx); } }
错误原因
编译失败的核心是生命周期推导不匹配。默认情况下,Deref::deref的方法签名被编译器推导为:
fn deref(&'b self) -> &'b Self::Target;
这里返回的引用生命周期与&self的临时生命周期'b绑定,而idx是循环内的局部变量,生命周期仅在当前迭代有效。但我们需要返回的引用生命周期与Idx持有的&'a Foo的生命周期'a(即foo的全局生命周期)绑定。
正确实现
显式指定deref方法的返回引用生命周期为'a,与Idx内部的Foo引用生命周期对齐:
use std::ops::Deref; struct Foo { xs: Vec<u8>, } struct Idx<'a>(&'a Foo, usize); impl<'a> Deref for Idx<'a> { type Target = u8; // 显式标注返回引用的生命周期为'a,与Idx持有的Foo引用一致 fn deref(&self) -> &'a u8 { &self.0.xs[self.1] } } fn main() { let foo = Foo { xs: vec!(10, 11, 12), }; let mut xs_refs: Vec<&u8> = vec!(); for i in 0..3 { let idx = Idx(&foo, i); xs_refs.push(&*idx); } }
原理说明
通过显式标注返回类型为&'a u8,我们向编译器表明:解引用Idx得到的引用,其有效性依赖于Foo的生命周期'a,而非&Idx的临时生命周期。这样编译器就能确认xs_refs中存储的引用在整个main函数内都有效,不会因idx的销毁而失效。
内容的提问来源于stack exchange,提问作者ajp
相关产品推荐
相关产品推荐

