换句话说,如果我定义了一个类型,例如
pub struct MyFloat(f64);
有可能有这样的东西吗?
let v = vec![MyFloat(0.),MyFloat(1.)];
let v_slice_f64 : &[f64] = v.slice_underlying_type();
assert_eq!(v_slice_f64, &[0.,1.]);
这是因为我想用 newtype 惯用法包装原生 f64,但我使用的一些库需要
&[f64]
作为其方法中的输入参数。
您尝试的操作并不安全,因为从技术上来说,
struct MyFloat(T)
不能保证与任意T
具有与T
相同的表示形式 - 即使在f64
的情况下也很可能如此。如果您控制 MyFloat
,则可以添加 #[repr(transparent)]
来提供该保证,然后使用 slice::from_raw_parts()
来获取变形切片。
或者,您可以使用非常流行的 bytemuck 板条箱来安全地执行相同的操作:
use bytemuck::{Pod, Zeroable};
#[derive(Pod, Zeroable, Copy, Clone)]
#[repr(transparent)]
struct MyFloat(f64);
fn main() {
let v = vec![MyFloat(0.), MyFloat(1.)];
let v_slice_f64: &[f64] = bytemuck::cast_slice(&v);
assert_eq!(v_slice_f64, &[0., 1.]);
}
特别是,bytemuck 的派生宏将确保您使用
#[repr(transparent)]
或等效项来使切片操作真正听起来。