我如何改变枚举然后 return 对枚举变体的引用?

How do I mutate an enum and then return a reference to an enum variant?

我有一个枚举,它可以包含编码类型 (i32) 或解码类型 (String)。

我的目标是编写一个将枚举转换为解码状态的函数,以及return一个引用,但我做不到:如果我先改变枚举的内容,我不能return 参考。

enum Foo {
    A(i32),
    B(String),
}

use Foo::*;

impl Foo {
    fn get_string(&mut self) -> &str {
        match self {
            A(i) => {
                let s = i.to_string();
                *self = B(s);
                &s
            }
            B(string) => string,
        }
    }
}

我明白了

error[E0515]: cannot return value referencing local variable `s`
  --> src/lib.rs:10:9
   |
10 | /         match self {
11 | |             A(i) => {
12 | |                 let s = i.to_string();
13 | |                 *self = B(s);
14 | |                 &s
   | |                 -- `s` is borrowed here
15 | |             }
16 | |             B(string) => string,
17 | |         }
   | |_________^ returns a value referencing data owned by the current function

error[E0382]: borrow of moved value: `s`
  --> src/lib.rs:14:17
   |
12 |                 let s = i.to_string();
   |                     - move occurs because `s` has type `String`, which does not implement the `Copy` trait
13 |                 *self = B(s);
   |                           - value moved here
14 |                 &s
   |                 ^^ value borrowed here after move

我想做的事可行吗?如果可以,我该怎么做?

您 return 的引用需要指向 Foo::B 中的数据,而不是您的局部变量 s。最简单的方法是分两步完成此操作——如有必要,首先进行转换,然后 return 引用。第一步后保证 *selfFoo::B,因此我们可以将匹配中的 A 分支标记为 unreachable!().

impl Foo {
    fn get_string(&mut self) -> &str {
        if let A(i) = *self {
            *self = B(i.to_string());
        }
        match *self {
            A(_) => unreachable!(),
            B(ref s) => s,
        }
    }
}

(请注意,我将模式匹配更改为 而不是 使用“匹配人体工程学”,因为这往往不会造成混淆。)