【问题标题】:Can't convert Iterators into js_sys::Array无法将迭代器转换为 js_sys::Array
【发布时间】:2021-04-02 09:33:15
【问题描述】:

我正在尝试实现一种方法来发送u32 的数组(如果可能的话,最终是usize 的数组of 数组),因为你不能只声明一个公共wasm_bindgen 类型的数组字段。但是,使用wasm_bindgenPR 1749 中概述的示例,我似乎无法将数组或切片转换为js_sys::Array;它仅适用于Vecs。我的问题是,为什么?见下文

pub fn test() -> js_sys::Array {
    let arr: [u32; 5] = [0,1,2,3,4];
    let slice = &arr[0..2];
    let vec: Vec<u32> = vec![0,1,2];
    arr.into_iter().map(JsValue::from).collect() // This doesn't work
    slice.into_iter().map(JsValue::from).collect() // Also doesn't work
    vec.into_iter().map(JsValue::from).collect() // Works as expected!     
}

具体错误为:the trait 'wasm_bindgen::cast::JsCast' is not implemented for 'u32'

数组和切片示例似乎不适用于任何数字类型、整数或浮点数。我唯一的想法是因为 PR 1749 中的实现似乎需要一个 ref,并且数组分配在堆栈上 FromIterator 对数组中的项目无效?

是否有其他方法可以实现我想要对数组执行的操作(通过wasm_bindgen 越过边界传递给 JS),或者如果没有,为什么?我很想知道。

【问题讨论】:

    标签: arrays rust iterator webassembly wasm-bindgen


    【解决方案1】:

    虽然 Rust 数组和切片有一个 into_iter 方法,但它返回的 Iteratoriter 方法相同,它迭代 references 到值而不是值本身。是的,这令人困惑。由于JsValue::from 是针对u32 而不是针对&amp;u32 实现的,因此您可以使用copied 方法将Iterator&lt;Item = &amp;u32&gt; 转换为Iterator&lt;Item = u32&gt;。固定工作示例:

    use wasm_bindgen::JsValue;
    use js_sys::Array;
    
    fn array_to_js_array(array: [u32; 5]) -> Array {
        array.iter().copied().map(JsValue::from).collect()     
    }
    
    fn slice_to_js_array(slice: &[u32]) -> Array {
        slice.iter().copied().map(JsValue::from).collect()    
    }
    
    fn vec_to_js_array(vec: Vec<u32>) -> Array {
        vec.into_iter().map(JsValue::from).collect()    
    }
    

    【讨论】:

    • 啊,我没有意识到 into_iter 对数组(和切片)的行为与对 vec 的行为不同。这就解释了!谢谢。我现在注意到数组(不是切片)的 linter 标志 into_iter 并说这很快就会成为一个硬错误,所以我想这个歧义正在得到解决。有一个单一的数组方法来做into_itervec 做的事情会很好,但我敢肯定这是有原因的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 2017-05-22
    • 2012-06-07
    • 2011-04-07
    • 2016-08-14
    • 1970-01-01
    • 2011-09-02
    相关资源
    最近更新 更多