如何在可变结构体中交换两个向量

3
以下是结构体定义:

struct:

struct Data {
    xs: Vec<i32>,
    ys: Vec<i32>
}

尝试将一个结构体的向量分配给另一个向量会导致错误:
impl Data {
    fn proc(&mut self) {
        self.xs = self.ys;
    }
}

错误是move occurs because self.ys has type Vec<i32>, which does not implement the Copy trait
这个结构体被借用为可变的,为什么不能从self.ys中移动呢?
2个回答

3

使用std::mem::swap函数进行就地交换值:

impl Data {
    fn proc(&mut self) {
        std::mem::swap(&mut self.xs, &mut self.ys);
    }
}

(播放区)

self.xs = self.ys无法工作,因为Vec未实现Copy:您需要使用.clone()复制ys


哦,别打我,我只是瞬间犯了一个错误。 - Netwave
1
谢谢,它确实有效。但是,我不明白为什么需要Copy。例如,在函数中将一个可变向量移动到另一个可变向量中是可能的,一旦这些向量被定义为局部变量。为什么在结构体中这样做就不起作用呢? - JoeDoe
@JoeDoe,你不能从&mut self移动。 - Netwave
1
@Netwave 所以,如果一个结构体被借用为&mut,那么就不可能从任何字段中移动值,对吗?如果是这样的话,是否是为了防止在字段中留下未初始化的值而进行的。我很好奇,通过将Vec :: new()分配给它,可以丢弃ys中的值,但无法使丢弃的值有用(即将其用作r-value)。 - JoeDoe
1
@JoeDoe,你的猜测大致正确。重新分配是可以的,那么旧值将被丢弃。或者使用std::mem::take来获取旧值的所有权,并用默认值或其他值替换它。但最终,这与执行mem::swap相同。 - Netwave

2

除了 @Smitop 的答案,你也可以将数据 Data 移动 到一个新的交换空间中。请注意,你不能从 &mut 移动,因此签名也必须更改:

impl Data {
    fn proc(self) -> Self {
        Self {
            xs: self.ys, ys: self.xs
        }
    }
}

Playground


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接