将枚举转换为 Rust 中的另一个枚举,同时有选择地移动包含的值

问题描述 投票:0回答:1

我有两个这样的枚举:

enum E1 {
  A { val: SomeValue1 },
  B(SomeValue2),
  C(SomeValue3),
}

enum E2 {
  A,
  B(SomeValue2),
  C(SomeValue3),
  D,
  E
}

此处

SomeValueX
类型未实现
Copy
Clone

我正在尝试编写以

E1
作为输入并执行以下操作的代码:

  1. 对包含的值执行一些操作。如果输入是
    E1::A(val)
    ,则需要取得
    val
    的所有权。
  2. 将输入转换为
    E2

目前我正在做这样的事情:

fn example(input: E1) -> E2 {
  match input {
    E1::A(val) => { do_something_with_a(val); E2::A },
    E1::B(val) => { do_something_with_b(&val); E2::B(val) },
    E1::C(val) => { do_something_with_c(&val); E2::C(val) },
  }
}

有什么方法可以清理这个问题并可能将 1. 和 2. 分成单独的函数吗?我没有成功,因为:

  • 如果转换函数 (2) 消耗了
    E1
    值,则
    E1::A(val)
    会丢失并且无法被
    do_something_with_a
    消耗。
  • 如果转换函数通过引用获取
    E1
    ,则无法构造
    E2::B
    E2::C
    变体。

我愿意根据需要更改枚举或使用宏。

rust enums borrow-checker
1个回答
0
投票

如果您确实更喜欢它作为两个功能,您可以更改操作顺序。先做 2,再做 1。

因此,您将拥有一个将

E1
解构为
E2
以及 可选
Option<SomeValue1>
作为元组的函数:

fn deconstruct_your2(input: E1) -> (E2, Option<SomeValue1>) {
match input {
    E1::A(val) => (E2::A, Option::Some(val)),
    E1::B(val) => (E2::B(val), Option::None),
    E1::C(val) => (E2::C(val), Option::None),
}

}

然后另一个函数借用

E2
并使用拥有
SomeValue1
的可选函数:

fn useInput_your1(input: &E2, input2: Option<Some1>) -> () {
match input {
    E2::A => do_something_with_a(input2.expect("intput error: you must provide Option::Some(x) input2 in case of A")),
    E2::B(val) => do_something_with_b(val),
    E2::C(val) => do_something_with_c(val),
    _ => {}
}

}

© www.soinside.com 2019 - 2024. All rights reserved.