rust - 在传输不可复制的值时实现就地枚举修改

标签 rust

<分区>

有没有一种方法可以让merge函数使用&mut self,消耗内部枚举值并在合并时将其插入新的Vector?我一直在与编译器抗争——PEBKAC,但是在哪里呢?

如果这不可能,是否可以通过在 Val 上实现 Clone trait 来解决这个问题? (但不是 Copy 特性!)

struct Val();

enum Foo {
    One(Val),
    Many(Vec<Val>),
}

impl Foo {
    pub fn merge(&mut self, other: Self) {
        match (*self, other) {
//             ^^^^^
// move occurs because `*self` has type `Foo`, which does not implement the `Copy` trait
// cannot move out of `*self` which is behind a mutable reference
//

            (Self::One(a), Self::One(b)) => *self = Self::Many(vec![a, b]),
            (Self::One(a), Self::Many(mut b)) => {
                b.insert(0, a);
                *self = Self::Many(b)
            }
            (Self::Many(mut a), Self::One(b)) => {
                a.push(b);
            }
            (Self::Many(mut a), Self::Many(b)) => {
                a.extend(b);
            }
        };
    }
}

最佳答案

这有什么棘手的是 One variant 要求始终存在一个值。你不能拿它的 T出去,甚至不是暂时的,因为你必须在它的位置放一些别的东西。如果是One(Option<T>)我们可以放一个None在那里,但带有 One(T)我们不能那样做。

你能做的就是临时替换*self空的 Many .然后生成替换对象并覆盖空对象,这样调用者就看不到它。

impl Foo {
    pub fn merge(&mut self, other: Self) {
        let this = std::mem::replace(self, Self::Many(vec![]));
        *self = match (this, other) {
            (Self::One(a), Self::One(b)) => Self::Many(vec![a, b]),
            (Self::One(a), Self::Many(mut b)) => {
                b.insert(0, a);
                Self::Many(b)
            }
            (Self::Many(mut a), Self::One(b)) => {
                a.push(b);
                Self::Many(a)
            }
            (Self::Many(mut a), Self::Many(b)) => {
                a.extend(b);
                Self::Many(a)
            }
        };
    }
}

关于rust - 在传输不可复制的值时实现就地枚举修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74695831/

相关文章:

rust - 这个 for 循环模式有没有名字,如果有,有没有更好的写法?

Rust 等同于具有相同泛型参数约束的 Swift 扩展方法?

rust - Rust 中 tribonacci 序列的惯用实现

Rust 从 fn : mismatched types 返回结果错误

rust - 实例构建效率低下?

rust - 使用 nom 从输入中识别 float

multithreading - 如何创建可在 Rust 多线程服务器中使用的结构?

rust - 如何使用 dyn 类型别名将生命周期参数添加到 Box<>

android - 如何在 Android/iOS 上调试 Rust?

rust - 对于 "big"结构,只使用引用是最惯用/最有效的吗?