提问人:gust 提问时间:10/28/2023 更新时间:10/28/2023 访问量:50
rustc 无法推断 trait 实现中的生存期
rustc cannot infer lifetime in trait implementations
问:
我有以下代码:
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)
}
}
}
rustc
告诉我:
Compiling playground v0.0.1 (/playground)
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
即使应该能够推断生存期,也无法这样做。最直接的方法是添加显式生存期签名;但是,在本例中,这是一个特征实现(std::convert::TryFrom
),因此我无法更改函数签名。有没有办法解决这个问题?try_from
rustc
答:
1赞
Anders Evensen
10/28/2023
#1
虽然您不能更改 的函数签名,但您可以在实现 时指定显式生存期,如下所示:try_from()
TryFrom
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)
}
}
}
这将按照您的预期进行编译(请参阅 playground)。
不期望能够省略和相同的生命周期;请参阅 Rustonomicon 的 Lifetime Elision 部分,特别是以下行:“对于标头,所有类型都是输入的。所以在输入位置上省略了两个寿命,而省略了一个。因此,如果要使它们相同,则必须显式提供这两个生存期。rustc
&Value
&InnerValue
impl
impl Trait<&T> for Struct<&T>
impl Struct<&T>
评论
impl<'a> TryFrom<&'a Value> for &'a InnerValue
和?我不完全熟悉什么样的推理是可能的,但似乎不应该有规则,然后为时已晚?fn try_from(value: &'a Value)
impl TryFrom<&Value> for &InnerValue
&InnerValue
value: &Value
Self
try_from