Rust - Как инициализировать массив структур, содержащих поле HashSet? - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть Instance структура с полем HashSet для хранения неупорядоченных чисел с легким удалением и добавлением с контролем дубликатов.

Затем есть другая структура с именем Matrix, которая содержит двумерный массив Instance struct.

Я создаю метод new() в признаке для Instance для использования при инициализации массива, но использование этого метода приводит к ошибке во время компиляции, говоря, что HashSet не реализует Copy trait.

Вот код:

#![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 реализации копирования, работающей с массивами. Может быть, есть другой способ реализовать это?

1 Ответ

2 голосов
/ 19 апреля 2020

Я явно что-то упустил, но не нашел HashSet реализации копирования, работающей с массивами.

Это потому, что ее нет! Copy означает, что тип является копируемым бит за битом. Это не может быть в случае типа, подобного HashSet<T>. Однако то, что HashSet<T> является инициализируемым по умолчанию. В сочетании с тем фактом, что массивы (до 32 элементов на данный момент) также инициализируются по умолчанию, вы можете использовать следующее:

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

, если вы добавите

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

( Постоянная ссылка на игровую площадку )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...