I want to do
pub fn col_vec<T:Sized, const DIM0: usize>(mat: [T; DIM0]) -> [[T; 1]; DIM0] {
unsafe { std::mem::transmute(mat) }
}
which is obviously safe to do. Rust rejects it as
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> vf\src\shape_arr.rs:22:14
|
22 | unsafe { std::mem::transmute(mat) }
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `[T; DIM0]` (this type does not have a fixed size)
= note: target type: `[[T; 1]; DIM0]` (this type does not have a fixed size)
Is there some way around this?
The above code does the same thing using safe operations. While
array::map()
does sometimes result in code generation, in this case, the compiler appears capable of optimizing it down to just a copy of the entire array (and, presumably, nothing at all within some larger algorithm). I would recommend using this option.Another option which is closer to
transmute()
is:This version uses
bytemuck
, a library for performing byte-reinterpreting conversions between arbitrary types as long as it is safe to do so (which theT: bytemuck::Pod
bound ensures). This is very flexible and can do any kind of matrix reshaping, but it has the disadvantage that the element type must meet thePod
constraint (it must not contain any pointers or padding, for example). This requirement is because, for individual conversions,bytemuck
only checks that the input and output have the same length, so it can be used to do things like turning[u32; 4]
into[u16; 8]
or similar reshaping at the byte level.