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>
>Solution :
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 withNcopies ofx. The type ofxmust 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).