Editor's note: This question was asked before Rust 1.0 and uses syntax which is no longer valid. Additionally, the specific problem in this question no longer occurs in Rust 1.0.
There is a struct that contains the only field, a fixed-width array of bytes. One would think that implementing traits from std::cmp
for it would be straightforward, but deriving doesn't work:
#[deriving(Eq)]
pub struct ID {
bytes: [u8, ..::constants::ID_SIZE]
}
src/id.rs:3:5: 3:40 error: mismatched types: expected `&&[u8]` but found `&[u8, .. 20]` ([] storage differs: expected `&` but found `20`)
src/id.rs:3 bytes: [u8, ..::constants::ID_SIZE]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of #[deriving]
src/id.rs:1:1: 2:4 note: expansion site
The documentation suggests that Eq is implemented for &[]
and ~[]
, not for fixed width array. Manual coercion to &[]
doesn't work either:
impl Eq for ID {
fn eq(&self, other: &ID) -> bool {
(&self.bytes).eq(&other.bytes)
}
}
src/id.rs:7:26: 7:38 error: mismatched types: expected `&&[u8, .. 20]` but found `&[u8, .. 20]` (expected &-ptr but found vector)
src/id.rs:7 (&self.bytes).eq(&other.bytes)
^~~~~~~~~~~~
src/id.rs:7:9: 7:39 error: failed to find an implementation of trait std::cmp::Eq for [u8, .. 20]
src/id.rs:7 (&self.bytes).eq(&other.bytes)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This line in Rust reference manual may explain it:
Expressions producing vectors of definite size cannot be evaluated in a context expecting a vector of indefinite size; one must copy the definite-sized vector contents into a distinct vector of indefinite size.
The motivation is unclear, but I guess it has something to do with storing the length.
Anyway, is it possible to compare two fixed-lenght arrays using the implementation for &[]
, without copying?
The documentation suggests that Eq is implemented for &[] and ~[], not for fixed width array.
Yes, that's because [T,..2] is a different type than [T,..3].
Anyway, is it possible to compare two fixed-lenght arrays using the implementation for &[], without copying?
Easily
impl Eq for ID {
fn eq(&self, other: &ID) -> bool {
self.bytes.iter().zip(other.bytes.iter()).all(|(a,b)| a == b)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With