[英]Why does Rust "From" trait implementation give lifetime error, but custom trait does not?
當我使用自定義特征時,以下代碼可以工作。 但我不明白為什么在嘗試使用內置“From”特征時它會失敗。
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`
由於您沒有為From<&SimpleEnum>
impl 提供任何生命周期,因此編譯器為&SimpleEnum
(以及參數value
)分配的生命周期與Self
(或&A
)的生命周期不同。 脫糖后, impl
將如下所示:
impl<'a, 'b> From<&'a SimpleEnum> for &'b A {
fn from(value: &'a SimpleEnum) -> Self {
if let SimpleEnum::A(value) = value {
value
} else {
panic!();
}
}
}
這是行不通的,因為Self
的生命周期'b
與value
的生命周期'a
不同。 您必須明確告訴編譯器這兩個生命周期是相同的:
impl<'a> From<&'a SimpleEnum> for &'a A {
fn from(value: &'a SimpleEnum) -> Self {
if let SimpleEnum::A(value) = value {
value
} else {
panic!();
}
}
}
差異與推斷的壽命有關。
您的自定義特征在參數和返回類型中都有引用; 由於生命周期省略規則,您的特征等同於以下內容:
trait FromCustom {
fn from_custom<'a>(value: &'a SimpleEnum) -> &'a A;
}
因此僅通過簽名,返回類型就綁定到參數的生命周期。
相反, From
特征是這樣寫的:
pub trait From<T>: Sized {
fn from(value: T) -> Self;
}
T
和Self
之間沒有生命周期的隱式鏈接,因為沒有明顯的生命周期在使用中。 因此,當您編寫實現時, &SimpleEnum
和&A
具有不同的生命周期,就像這樣寫:
impl<'a, 'b> From<&'b SimpleEnum> for &'a A {
fn from(value: &'b SimpleEnum) -> Self {
if let SimpleEnum::A(value) = value {
value // error
} else {
panic!();
}
}
}
推斷的是,任何生命周期的&SimpleEnum
都可以用來創建具有任何生命周期的&A
,這是不正確的。 相反,您需要傳達具有特定生命周期的&SimpleEnum
可用於創建具有該生命周期的&A
。 您可以通過自己將生命周期鏈接在一起來做到這一點:
impl<'a> From<&'a SimpleEnum> for &'a A {
fn from(value: &'a SimpleEnum) -> Self {
if let SimpleEnum::A(value) = value {
value
} else {
panic!();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.