有没有办法让merge函数使用&mut self,使用内部枚举值,并在合并时将其推送到新的向量上?我一直在和编译器抗争--PEBKAC,但在哪里呢?

如果这是不可能的,可以通过在Val上实现Clone特征来修复它吗?(但不能修复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的变体要求始终存在一个值.你不能把它的T拿出来,即使是暂时的,因为你必须把其他东西放在它的位置上.如果它是One(Option<T>),我们可以在那里加None,但如果是One(T),我们就不能这么做.

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

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相关问答推荐

Rust TcpStream不能在读取后写入,但可以在不读取的情况下写入.为什么?

返回的future 不是`发送`

有没有办法在Rust中配置常量变量的值?

有没有办法避免在While循环中多次borrow `*分支`

`Pin`有没有不涉及不安全代码的目的?

允许 rust 迹 struct 条目具有多种类型

Rust中WPARAM和VIRTUAL_KEY的比较

在Rust内联程序集中使用字符串常量

对reqwest提供的这种嵌套JSON struct 进行反序列化

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

使用占位符获取用户输入

如何以与平台无关的方式将OsString转换为utf-8编码的字符串?

tokio::spawn 有和没有异步块

Rust与_有何区别?

一个函数调用会产生双重borrow 错误,而另一个则不会

在 Rust 中,为什么整数溢出有时会导致编译错误或运行时错误?

LinkedList::drain_filter::drop 中 DropGuard 的作用是什么?

Rust 中函数的类型同义词

编写 TOML 文件以反序列化为 struct 中的枚举

为什么这里需要类型注解?