Rust 匹配模式中变量的生存期

Rust 匹配模式中变量的生存期,rust,lifetime,Rust,Lifetime,正在尝试编译以下代码: #[derive(Show)] pub enum E1 { A, B, } #[derive(Show)] pub enum E2 { X(E1), Y(i32), } impl std::fmt::String for E1 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { std::fmt::Show::f

正在尝试编译以下代码:

#[derive(Show)]
pub enum E1 {
    A,
    B,
}
#[derive(Show)]
pub enum E2 {
    X(E1),
    Y(i32),
}

impl std::fmt::String for E1 {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        std::fmt::Show::fmt(self, f)
    }
}

impl std::fmt::String for E2 {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        std::fmt::Show::fmt(self, f)
    }
}

impl std::error::Error for E2 {
    fn description(&self) -> &'static str {
        match *self {
            E2::X(x) => {
                let d: &'static str = x.description();
                d
            },
            E2::Y(_) => "Unknown error",
        }
    }
}

impl std::error::Error for E1 {
    fn description(&self) -> &'static str {
        match *self {
            E1::A => "Error A",
            E1::B => "Error B",
        }
    }
}

fn main() { }
产生一个错误:

a.rs:17:39:17:40错误:`x`活得不够长
a、 rs:17设d:&'static str=x.description();
^
注意:引用必须在静态生存期内有效。。。
a、 rs:15:9:21:10注:……但借用值仅对15:8的比赛有效
a、 rs:15场比赛*赛尔夫{
a、 rs:16 E2::X(X)=>{
a、 rs:17设d:&'static str=x.description();
a、 rs:18天
a、 rs:19},
a、 rs:20 E2::Y()=>“未知错误”
...
a、 rs:15:15:15:20错误:无法移出借用的内容
a、 rs:15场比赛*赛尔夫{
^~~~~
a、 rs:16:19:16:20注意:正在尝试将值移动到此处
a、 rs:16 E2::X(X)=>{
^
a、 rs:16:19:16:20帮助:要防止移动,请使用'ref x'或'ref mut x'通过引用捕获值
a、 rs:16 E2::X(X)=>{
^
错误:由于之前的两个错误而中止
将匹配模式更改为
E2::X(ref X)
可能会产生一个更详细的错误,但让我同样感到困惑:

a.rs:16:19:16:24错误:由于需求冲突,无法推断模式的适当生存期
a、 rs:16 E2::X(参考X)=>{
^~~~~
a、 rs:17:39:17:40注:首先,生命不能超过17:38的表达。。。
a、 rs:17设d:&'static str=x.description();
^
a、 rs:17:39:17:40注意:…因此指针在其生存期之外不会被解除引用
a、 rs:17设d:&'static str=x.description();
^
a、 rs:15:9:21:10注:但是,生命周期必须在15:8对比赛有效。。。
a、 rs:15场比赛*赛尔夫{
a、 rs:16 E2::X(参考X)=>{
a、 rs:17设d:&'static str=x.description();
a、 rs:18天
a、 rs:19},
a、 rs:20 E2::Y()=>“未知错误”
...
a、 rs:16:19:16:24注:…因此该变量在声明时有效
a、 rs:16 E2::X(参考X)=>{
^~~~~
错误:由于上一个错误而中止

在我看来,
x
只需活到
x.description()
返回,但编译器似乎认为它需要超过整个匹配块。为什么?为什么它还坚持在复制时将
x
视为引用可能更符合逻辑?

至于
x
ref x
x
将不起作用,因为您只有对
self
的引用因此,无法将
E1
值移出,您所能做的就是引用它

但现在更重要的是:您对
描述
方法的定义不正确,而Rust编译器并没有就此向您发出警告,而是让您的生活变得不愉快

这是
描述
方法的实际定义:

fn description(&self) -> &str;
请仔细注意:
&str
,而不是
&static str
。编译器应该反对签名中的
'static
,但遗憾的是,它没有。(这是的主题,由于这个问题而提交。)通常情况下,指定更大的生存期会很好,因为它只会将其缩小到大小,但在某些情况下,它不会做您认为它会特别做的事情,它更改了
E1
描述
方法以返回具有自己生存期的
&str
,但在
E2
定义中它是仍然想返回
&'static str
。当然,
x
引用不是
'static
,所以它无法返回。令人困惑,是吗?别担心,这绝不是你的错


要解决此问题,请删除所有出现的
'static
,以匹配特征定义。然后,因为
x
self
内,因此生命周期将正确排列。

感谢扩展的错误消息!谢谢。但仍然对一件事感到困惑:
x
引用肯定没有长的enough life,但不管
x.description()
的输出是否应该具有life
'static
,否?或者这不是由于更改了生存时间,但编译器没有告诉我这一点?@dhardy:your
description
方法不应该处理
&的static str
以及它部分“修复”的事实这对你来说(宽宏大量,允许
'静态的
,而不是强烈反对)是让你绊倒的。是的,所以编译器在没有告诉我的情况下降级了一辈子。:(谢谢你帮我省去了麻烦!