当我使用自定义trait时,下面的代码可以工作,但是我不明白为什么当尝试使用内置的"From" trait时,它会失败。
struct A {
x: isize,
}
enum SimpleEnum {
A(A),
B(u8),
}
trait FromCustom {
fn from_custom(value: &SimpleEnum) -> &A;
}
impl FromCustom for &SimpleEnum {
fn from_custom(value: &SimpleEnum) -> &A {
if let SimpleEnum::A(value) = value {
value // NO error
} else {
panic!();
}
}
}
impl From<&SimpleEnum> for &A {
fn from(value: &SimpleEnum) -> Self {
if let SimpleEnum::A(value) = value {
value // error
} else {
panic!();
}
}
}
错误:
error: lifetime may not live long enough
--> rust_pst_bin/src/main.rs:55:13
|
53 | fn from(value: &SimpleEnum) -> Self {
| - ---- return type is &'2 A
| |
| let's call the lifetime of this reference `'1`
54 | if let SimpleEnum::A(value) = value {
55 | value // error
| ^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
2条答案
按热度按时间xfb7svmp1#
由于您没有为
From<&SimpleEnum>
impl提供任何生存期,编译器会为&SimpleEnum
(以及参数value
)分配一个与Self
(或&A
)的生存期 * 不同 * 的生存期。这是行不通的,因为
Self
的生存期'b
与value
的生存期'a
不同,你必须明确告诉编译器这两个生存期是相同的:Playground
o4tp2gmn2#
这种差异与推断的寿命有关。
您的自定义trait在参数和返回类型中都有引用;由于lifetime elision rules,您的trait等效于以下内容:
因此,仅通过签名,返回类型就绑定到参数的生存期。
相比之下,
From
特征是这样写的:T
和Self
之间没有生命期的隐式链接,因为没有明显的生命期在使用中,因此当你编写实现时,&SimpleEnum
和&A
有 * 不同的 * 生命期,就像这样写:由此推断,any lifetime的
&SimpleEnum
可以用来创建 any lifetime的&A
,这是不正确的。相反,您需要传达具有特定lifetime的&SimpleEnum
可以用来创建具有该lifetime的&A
。您可以自己将这些lifetime链接在一起: