[英]How do I mutate an enum and then return a reference to an enum variant?
I have an enum that can hold either an encoded type ( i32
) or a decoded type ( String
).我有一个可以保存编码类型(
i32
)或解码类型( String
)的枚举。
My goal is to write a function that converts the enum to the decoded state, and return a reference, but I can't do it: if I change the content of the enum first, I cannot return a reference.我的目标是编写一个 function 将枚举转换为解码的 state,并返回一个引用,但我做不到:如果我先更改枚举的内容,我无法返回一个引用。
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,
}
}
}
I get我明白了
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
Is what I want to do possible?我想做的事可能吗? If so, how can I do it?
如果是这样,我该怎么做?
The reference you return needs to point to the data inside Foo::B
, not to your local variable s
.您返回的引用需要指向
Foo::B
中的数据,而不是您的局部变量s
。 It's easiest to do this in two steps – first do the conversion if necessary, then return the reference.最简单的方法是分两步完成——如果需要,首先进行转换,然后返回引用。 After the first step it's guaranteed that
*self
is Foo::B
, so we can mark the A
branch in the match as unreachable!()
.在第一步之后,保证
*self
是Foo::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,
}
}
}
(Note that I changed pattern matching to not use "match ergonomics", since this tends to be less confusing.) (请注意,我将模式匹配更改为不使用“匹配人体工程学”,因为这往往不那么令人困惑。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.