为引用类型实现TryFrom时如何指定生命周期?
Rust中实现
&InnerValue的TryFrom<&Value>时的生命周期问题 尝试为&InnerValue实现TryFrom<&Value> trait时遇到生命周期报错,代码如下:
use anyhow; struct InnerValue; enum Value { Int(i32), Other(InnerValue), } impl TryFrom<&Value> for &InnerValue { type Error = anyhow::Error; fn try_from(value: &Value) -> Result<Self, Self::Error> { match value { Value::Int(..) => anyhow::bail!("Ignore this case"), Value::Other(inner) => Ok(inner) } } }
编译器报错信息:
error: lifetime may not live long enough --> src/lib.rs:16:36 | 13 | fn try_from(value: &Value) -> Result<Self, Self::Error> { | - ------------------------- return type is Result<&'2 InnerValue, <&'2 InnerValue as TryFrom<&Value>>::Error> | | | let's call the lifetime of this reference `'1` ... 16 | Value::Other(inner) => Ok(inner) | ^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: could not compile `playground` (lib) due to previous error
问题核心是编译器无法自动推断输入引用和输出引用的生命周期关联,且不能修改TryFrom trait的函数签名,解决办法如下:
解决办法:显式绑定生命周期参数
为TryFrom的实现添加显式的生命周期参数,将输入的&Value和输出的&InnerValue的生命周期绑定在一起,让编译器明确两者的生命周期一致。修正后的代码:
use anyhow; struct InnerValue; enum Value { Int(i32), Other(InnerValue), } impl<'a> TryFrom<&'a Value> for &'a InnerValue { type Error = anyhow::Error; fn try_from(value: &'a Value) -> Result<Self, Self::Error> { match value { Value::Int(..) => anyhow::bail!("Ignore this case"), Value::Other(inner) => Ok(inner) } } }
原理说明
TryFrom trait的定义本身没有指定生命周期,但当为引用类型实现该trait时,必须显式声明生命周期绑定——因为编译器无法自动推断返回的引用必须依赖于输入引用的生命周期。通过impl<'a>声明生命周期参数'a,并将其同时应用到输入的&'a Value和输出的&'a InnerValue上,就能让编译器确认返回的引用不会超过输入引用的生命周期,从而解决报错。
内容的提问来源于stack exchange,提问作者gust
相关产品推荐
相关产品推荐

