I'm writing code that works with strings and want to compare [u8; n] and Option<&[u8]>. I wrote the code below, but I couldn't compile this.
let bytes = "text....".as_bytes();
let slice = bytes.get(1..3); // : Option<&[u8]>
if Some(b"0x") == slice {
// ^^^^^ expected array `[u8; 2]`, found slice `[u8]`
//
// note: expected enum `std::option::Option<&[u8; 2]>`
// found enum `std::option::Option<&[u8]>
}
The two below could be compiled.
match expression
match slice {
Some(b"0x") => {}
_ => {}
}
Manually specify the type as &[u8] (instead of the inferred [u8; 2]).
let fixed_slice: &[u8] = b"0x";
if Some(fixed_slice) == slice {
// compilable
}
Compared to the compilable ones, the first one also seems fine to me.
I wanted to write in the first way, but is it not compilable due to some restriction?
Unfortunately I don't think we can add PartialEq<Option<&[T]>> for Option<&[T; N]> (I think it would be a breaking change), but you could instead use if let, like so
It seems that the &[u8; 2] is coerced into a &[u8] for only the former expression. My guess is that the compiler does not attempt any coercions for the receiver (left argument to == ), but can then coerce the right argument to have a matching type.
This is the simplest solution, but I hadn't tried it. I would use this. I didn't expect to be able to compile with this.
Thank you for answers. I now know that I can also write with if let or matches!.