napi-rs v2 迁移至 v3:JsTypedArrayValue 替代类型适配实现咨询
napi-rs v2 迁移至 v3:JsTypedArrayValue 替代类型适配实现咨询
我刚好在最近的项目里完成了napi-rs从v2到v3的类似迁移,给你整理下适配的核心思路和修改后的代码实现:
迁移核心变化点
napi-rs v3把原来通用的JsTypedArrayValue拆分成了具体的强类型数组(如Uint8Array/Int8Array等),不再有统一的入口类型,所以我们需要针对每个数组类型单独处理数据转换,同时调整错误逻辑以符合v3的规范。
修改后的完整实现
下面是适配v3版本的代码,我优化了错误处理(替换panic为标准JsResult错误返回),并用宏减少了重复代码:
use napi::{bindgen_prelude::*, Error, Status}; use polars::prelude::*; // 宏:批量生成不同类型数组的转换逻辑 macro_rules! typed_array_to_series { ($arr:expr, $polars_type:ident) => {{ let slice = $arr.as_slice()?; let chunked_arr = ChunkedArray::<$polars_type>::from_slice("", slice); Ok(chunked_arr.into()) }}; } // 统一入口函数:自动匹配输入的TypedArray类型并转换为Series pub fn from_typed_array(env: &Env, value: Value) -> JsResult<Series> { // 依次尝试匹配所有支持的TypedArray类型 if let Ok(uint8_arr) = value.try_into::<Uint8Array>() { typed_array_to_series!(uint8_arr, UInt8Type) } else if let Ok(int8_arr) = value.try_into::<Int8Array>() { typed_array_to_series!(int8_arr, Int8Type) } else if let Ok(uint16_arr) = value.try_into::<Uint16Array>() { typed_array_to_series!(uint16_arr, UInt16Type) } else if let Ok(int16_arr) = value.try_into::<Int16Array>() { typed_array_to_series!(int16_arr, Int16Type) } else if let Ok(uint32_arr) = value.try_into::<Uint32Array>() { typed_array_to_series!(uint32_arr, UInt32Type) } else if let Ok(int32_arr) = value.try_into::<Int32Array>() { typed_array_to_series!(int32_arr, Int32Type) } else if let Ok(float32_arr) = value.try_into::<Float32Array>() { typed_array_to_series!(float32_arr, Float32Type) } else if let Ok(float64_arr) = value.try_into::<Float64Array>() { typed_array_to_series!(float64_arr, Float64Type) } else if let Ok(int64_arr) = value.try_into::<Int64Array>() { typed_array_to_series!(int64_arr, Int64Type) } else if let Ok(uint64_arr) = value.try_into::<Uint64Array>() { typed_array_to_series!(uint64_arr, UInt64Type) } else { // 返回标准napi错误而非panic,符合Node.js扩展的错误处理规范 Err(Error::new( Status::InvalidArg, format!("Unsupported typed array type: {}", value.get_type()), )) } }
关键适配细节
- 强类型数组处理:针对每个具体的数组类型(如
Uint8Array),通过try_into::<T>从通用Value类型转换而来 - 数据访问:用每个数组类型自带的
as_slice()方法获取底层数据切片(返回JsResult<&[T]>,自带错误处理) - 错误规范:移除原代码中的
panic!,改用JsResult返回标准napi错误,避免导致Node.js进程崩溃 - 代码复用:通过宏
typed_array_to_series封装重复的转换逻辑,减少代码冗余
如果你的绑定逻辑需要直接暴露给JavaScript,napi-rs的bindgen会自动识别Value类型参数,并支持传入任意TypedArray类型。
内容来源于stack exchange
相关产品推荐
相关产品推荐

