Rust - 如何初始化包含 HashSet 字段的结构数组?

Rust - How to initialize array of structs containing HashSet field?

我有 Instance 带有 HashSet 字段的结构,用于存储无序数字,易于删除和添加重复控件。

然后还有一个结构体Matrix,里面存放着一个Instance结构体的二维数组

我在trait中为Instance创建了new()方法用于数组初始化,但是使用这个方法在编译时报错,说HashSet没有实现Copy 特征。

代码如下:

#![allow(unused)]
use std::collections::HashSet;

struct Instance {
    ids: HashSet<u8>,
    value: u8,
}

trait IsInstance {
    fn new() -> Instance;
}

impl IsInstance for Instance {
    fn new() -> Instance {
        Instance {
            ids: [1, 2, 3, 5].iter().cloned().collect(),
            value: 0,
        }
    }
}

/*
Line below is commented due to error:

error[E0204]: the trait `Copy` may not be implemented for this type
  --> src/main.rs:26:6
   |
5  |     ids: HashSet,
   |     ---------------- this field does not implement `Copy`
...
26 | impl Copy for Instance {}
   |      ^^^^

*/
//impl Copy for Instance {}

impl Clone for Instance {
    fn clone(&self) -> Instance {
        Instance {
            ids: self.ids,
            value: self.value,
        }
    }
}

struct Matrix {
    instances: [[Instance; 4]; 4],
    status: u8,
}

fn main() {
    let mut m = Matrix {
        instances: [[Instance::new(); 4]; 4],
        status: 0,
    };
}

编译此错误:

error[E0507]: cannot move out of `self.ids` which is behind a shared reference
  --> src/main.rs:42:18
   |
42 |             ids: self.ids, 
   |                  ^^^^^^^^ move occurs because `self.ids` has type `std::collections::HashSet<u8>`, which does not implement the `Copy` trait

error[E0277]: the trait bound `Instance: std::marker::Copy` is not satisfied
  --> src/main.rs:60:22
   |
60 |         instances : [[Instance::new(); 4]; 4],
   |                      ^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `Instance`
   |
   = note: the `Copy` trait is required because the repeated element will be copied

error[E0277]: the trait bound `[Instance; 4]: std::marker::Copy` is not satisfied
  --> src/main.rs:60:21
   |
60 |         instances : [[Instance::new(); 4]; 4],
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `[Instance; 4]`
   |
   = note: the `Copy` trait is required because the repeated element will be copied

有什么方法可以正确初始化这个数组吗?我显然错过了一些东西,但没有找到 HashSet 复制实现与数组一起使用。也许还有另一种方法来实现这个?

I clearly missed something, but didn't find HashSet copy implementation working with arrays.

那是因为没有! Copy 表示类型是可逐位复制的。这不可能是 HashSet<T> 这样的类型的情况。但是 HashSet<T> 是默认可初始化的。结合数组(目前少于 32 个元素)也是默认可初始化的事实,您可以使用以下内容:

let mut m = Matrix {
    instances: Default::default(),
    status: 0,
};

如果你添加

impl Default for Instance {
    fn default() -> Self {
        Self::new()
    }
}

(Permalink to the playground)