写点什么

数据类型的转换

作者:Miracle
  • 2025-09-23
    四川
  • 本文字数:1490 字

    阅读完需:约 5 分钟

数据类型的转换

我们使用这个紧凑的方式保存了这个数据类型。所以但是我们所以我们在装入的时候取出来的时候都需要对数据类型进行切换。有时候需要把那个 U8 的那个切片转化成对应类型的切片,比如说 u16 啊,u32,i64,f32 等等。所以我们要使用一个 bytemuck 这样一个库,这个库是用来做安全做各种把数据块当成无类型的数据块来处理,然后在使用的时候再把它加上类型,这样的话就可以在不同类型。我们确信它的大小和内存布局是一样的情况下,我们可以进行安全的转换。

use tinyvec::TinyVec;type InlineVec = TinyVec<[u8; 28]>;use bytemuck::{AnyBitPattern, cast_slice};pub(crate) fn get_bits<T: AnyBitPattern>(v: &InlineVec, idx: usize)-> Option<T> {    let slice = cast_slice::<u8, T>(v.as_slice());    slice.get(idx).cloned()}
复制代码

上面的代码对 inline 的 TinyVec 按照需要的类型进行转换


macro_rules! impl_inline_vec {    ($variant:ident, $ty:ty) => {        impl From<&[$ty]> for Dynamic {            fn from(vec: &[$ty]) -> Self {                let mut tiny: TinyVec<[u8; 28]> = TinyVec::new();                tiny.extend_from_slice(bytemuck::cast_slice(vec));                Dynamic::$variant(tiny)            }        }
impl TryFrom<Dynamic> for Vec<$ty> { type Error = DynamicErr; fn try_from(value: Dynamic) -> Result<Self, Self::Error> { match value { Dynamic::$variant(vec) => { let slice = bytemuck::cast_slice::<u8, $ty>(vec.as_slice()); Ok(slice.to_vec()) } _ => Err(DynamicErr::TypeMismatch), } } } };}
复制代码


使用上面的宏可以自动生成转化的代码

impl_inline_vec!(Bytes, u8);impl_inline_vec!(VecU16, u16);impl_inline_vec!(VecI16, i16);impl_inline_vec!(VecU32, u32);impl_inline_vec!(VecI32, i32);impl_inline_vec!(VecF32, f32);
复制代码

这样使用上面这两个代码,我们就让我们的 dynamic 具有存储这个各种类型的数值数组的功能,并且效率非常高,在这个 28 自己能放的情况,放得下的情况下,全部都放在 28 字节之内。这样的话可以放 28 个 byte,如果是 short 的话可以放 14 个。如果是 int32 的话,我们可以放 7 个

下面是动态标量初始化的宏


macro_rules! impl_dynamic_scalar {    ($variant:ident, $ty:ty) => {        impl From<$ty> for Dynamic {            fn from(value: $ty) -> Self {                Dynamic::$variant(value)            }        }
impl TryFrom<Dynamic> for $ty { type Error = DynamicErr; fn try_from(value: Dynamic) -> Result<Self, Self::Error> { match value { Dynamic::$variant(v) => Ok(v), _ => Err(DynamicErr::TypeMismatch), } } } };}
复制代码


以及使用宏生成初始化的代码

impl_dynamic_scalar!(Bool, bool);impl_dynamic_scalar!(U8, u8);impl_dynamic_scalar!(I8, i8);impl_dynamic_scalar!(U16, u16);impl_dynamic_scalar!(I16, i16);impl_dynamic_scalar!(U32, u32);impl_dynamic_scalar!(I32, i32);impl_dynamic_scalar!(F32, f32);impl_dynamic_scalar!(I64, i64);impl_dynamic_scalar!(F64, f64);impl_dynamic_scalar!(String, SmolStr);
复制代码


用户头像

Miracle

关注

三十年资深码农 2019-10-25 加入

还未添加个人简介

评论

发布
暂无评论
数据类型的转换_Miracle_InfoQ写作社区