问题
I'm trying to pack columnar data so that it can be sent to a server.
I wanted to be able to pass any suitable vector to the sending function, so I did this (brief version):
enum Column {
Short(Vec<i16>),
Int(Vec<i32>),
}
impl Column {
fn as_bytes(&mut self) -> &[u8] {
use Column::*; // weird
match self {
Short(vec) => unsafe { (vec.align_to::<u8>()).1 }, //why the ::?
Int(vec) => unsafe { (vec.align_to::<u8>()).1 },
}
}
}
This works ok. However, if I rewrite the match with an or pipe:
impl Column {
fn as_bytes_succinct(&mut self) -> &[u8] {
use Column::*;
match self {
Short(vec) | Int(vec) => unsafe { (vec.align_to::<u8>()).1 },
}
}
}
I get
expected
i16
, foundi32
How/Why is the brief writing different from the explicit one?
回答1:
Rust is a statically typed language, so every object has a known type at compile-time. Your match in the last example is equivalent to the following code:
let vec: Vec<???> = match self {
Short(v) | Int(v) => v,
};
unsafe { vec.align_to() }.1
What type type should vec
have then? Moreover, there are 2 different paths for align_to
, i.e. <[i16]>::align_to
and <[i32]>::align_to
, which may have a different implementation with a specialization feature.
来源:https://stackoverflow.com/questions/62819390/difficulty-aggregating-matches-with