给定使用 newtype 习惯用法定义的类型上的 rust `Vec`,有没有办法获得底层原始类型的切片?

问题描述 投票:0回答:1

换句话说,如果我定义了一个类型,例如

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]
作为其方法中的输入参数。

rust
1个回答
0
投票

您尝试的操作并不安全,因为从技术上来说,

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)]
或等效项来使切片操作真正听起来。

© www.soinside.com 2019 - 2024. All rights reserved.