Nov 22, 2018
Here are some examples of comparing vectors, arrays, slices, and bytes that I’ve confused more than once.
Using the hex crate we can
get back Result
of vector of u8
s or FromHexError
.
extern crate hex;
fn main() {
let res = hex::decode("48656c6c6f20776f726c6421");
println!("res: {}", res);
}
Running outputs:
$ cargo run --example main
Compiling pals v0.1.0 (/home/verygoodwebsite/posts/example1)
Finished dev [unoptimized + debuginfo] target(s) in 0.38s
Running `target/debug/examples/main`
res: Ok([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33])
hex::decode
returns a Result
around a vector of u8
s or an error.
Surprisingly to me this compiles:
extern crate hex;
fn main() {
let x = hex::decode("48656c6c6f20776f726c6421");
let y: [u8; 12] = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33];
assert_eq!(x.unwrap(), y);
}
I suppose it shouldn’t be too much of a surprise; the values within the two are equal.
a byte string is an array of chars; how does that compare with the array?
fn main() {
let y: [u8; 12] = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33];
let z = b"Hello world!";
assert_eq!(y, z);
}
Running outputs:
$ cargo run --example main
Compiling pals v0.1.0 (/home/verygoodwebsite/post/example2)
error[E0277]: can't compare `[u8; 12]` with `&[u8; 12]`
--> examples/main.rs:12:5
|
12 | assert_eq!(y, z);
| ^^^^^^^^^^^^^^^^^ no implementation for `[u8; 12] == &[u8; 12]`
|
= help: the trait `std::cmp::PartialEq<&[u8; 12]>` is not implemented for `[u8; 12]`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
This doesn’t compile. A byte string, e.g. b"my byte string"
, is a reference to an array of unsigned 8-bit ints
. The values are equal, but we can’t compare a reference to an actual block of data.
what happens if we compare z
with a pointer to y
?
fn main() {
let y: [u8; 12] = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33];
let z = b"Hello world!";
assert_eq!(&y, z);
}
yep! It compiles.
Same is true if we dereference the z
:
fn main() {
let y: [u8; 12] = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33];
let z = b"Hello world!";
assert_eq!(y, *z);
}
Using same example, here’s how a &str
slice and bytes compare:
fn main() {
let z: &[u8; 12] = b"Hello world!";
let aa: &str = "Hello world!";
assert_eq!(aa.as_bytes(), z);
}
Use the .as_bytes
(or mutable version .as_bytes_mut
) method to convert to bytes.
Related tags: