I'm trying to implement a simple hash table with external chaining in Rust but having trouble with the table declaration. I declared the table as such:
static mut _HASH_TABLE: [Option<Box<MemoryMap>>; (std::u16::MAX -1) as usize] = [None; (std::u16::MAX -1) as usize];
with the MemoryMap
being a dynamic linked list
pub struct MemoryMap {
entry: SimpleEntry,
next: Option<Box<MemoryMap>>,
}
impl MemoryMap {
pub fn new(init_key: String, init_value: Box<dyn Storable>) -> MemoryMap {
MemoryMap {
entry: SimpleEntry::new(init_key, init_value),
next: None,
}
}
//...
}
pub struct SimpleEntry {
key: String,
value: Box<dyn Storable>,
}
impl SimpleEntry {
pub fn new(key: String, value: Box<dyn Storable>) -> SimpleEntry {
SimpleEntry { key, value }
}
//...
}
That said, I get this error
5 | static mut _HASH_TABLE: [Option<Box<MemoryMap>>; (std::u16::MAX -1) as usize] = [None; (std::u16::MAX -1) as usize];
| ^^^^ the trait `Copy` is not implemented for `Box<MemoryMap>`
|
= note: required for `Option<Box<MemoryMap>>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
and I can't understand why elements of the arrays have to be copied since I was expecting the array taking ownership of the Box<MemoryMap>
I can't understand why elements of the arrays have to be copied since I was expecting the array taking ownership of the
Box<MemoryMap>
When you write
[None; (std::u16::MAX -1) as usize]
the system needs to take the one value you gave it, and duplicate it std::u16::MAX - 1
times in order to fill the array. To do that, it uses Copy
:
A repeat expression
[x; N]
, which produces an array withN
copies ofx
. The type ofx
must beCopy
.
That can not work here because even if the None
value is trivial, as far as Rust is concerned Option<T>
implements Copy
iff T
implements Copy
, and Box<_>
does not implement Copy
. So you need to implement an alternate initialisation method. Like the one linked by @cafce25, or using once_cell
/ lazy_static
in order to have a global which is (lazy-) initialised at runtime, and would likely be something like a Vec
.
Though frankly I don't get why you're even creating a global mutable thing, let alone one initialised a fixed 65k entries (of 64 bit pointers).