【问题标题】:Rust wasm-bindgen struct with stringRust wasm-bindgen 结构与字符串
【发布时间】:2021-09-15 12:21:42
【问题描述】:

我正在尝试导出以下结构:

#[wasm_bindgen]
#[derive(Eq, PartialEq, Debug, Clone)]
pub enum TokenType {
    KeywordLiteral,
    NumberLiteral,
    Operator,
    Separator,
    StringLiteral,
}

#[wasm_bindgen]
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct Token {
    pub typ: TokenType,
    pub val: String,
}

但我得到了:

error[E0277]: the trait bound `token::TokenType: std::marker::Copy` is not satisfied
  --> src\tokenizer\token.rs:17:14
   |
14 | #[wasm_bindgen]
   | --------------- required by this bound in `__wbg_get_token_typ::assert_copy`
...
17 |     pub typ: TokenType,
   |              ^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `token::TokenType`

还有:

error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
  --> src\tokenizer\token.rs:18:14
   |
14 | #[wasm_bindgen]
   | --------------- required by this bound in `__wbg_get_token_val::assert_copy`
...
18 |     pub val: String,

我可以将#[derive(Copy)] 添加到TokenType,但不能添加到String。

我是 rust 新手,非常感谢您的帮助。

【问题讨论】:

    标签: rust wasm-bindgen


    【解决方案1】:

    根据wasm-bindgen#1985,结构的公共字段必须为Copy,以便自动生成的访问器起作用。

    您可以将字段设为私有,也可以使用#[wasm_bindgen(skip)] 对其进行注释,然后直接实现getter 和setter。

    在 wasm-bindgen 的文档中有一个 example provided 描述了如何编写这些:

    #[wasm_bindgen]
    pub struct Baz {
        field: i32,
    }
    
    #[wasm_bindgen]
    impl Baz {
        #[wasm_bindgen(constructor)]
        pub fn new(field: i32) -> Baz {
            Baz { field }
        }
    
        #[wasm_bindgen(getter)]
        pub fn field(&self) -> i32 {
            self.field
        }
    
        #[wasm_bindgen(setter)]
        pub fn set_field(&mut self, field: i32) {
            self.field = field;
        }
    }
    

    当对象在 wasm 和 js 之间共享时,js 对象只包含指向 wasm 运行时内存中结构的指针。当您从 JS 访问字段时,它会通过一个已定义的属性,该属性对 wasm 代码进行函数调用,询问它的属性值(您可以将 wasm 内存视为位 UInt8Array)。

    要求对象为Copy 可能是为了避免在自动生成这些getter 和setter 时出现意外。如果您手动实现它们,您可以在 JS 中具有相同的行为,并且能够控制在 rust 端设置的内容。

    【讨论】:

    • 所以不可能在结构中简单地有一个String?
    • 那将如何编译成打字稿?
    • 我编辑了答案以澄清。您可以在结构中随意使用字符串,如果您想使用自动生成的访问器,这些字符串不能是 pub。
    • 所以你告诉我我可以有一个 getter 和 setter 但不能直接将 String 暴露给 JavaScript?
    • 啊,我刚刚又读了一遍你的帖子。我明白了,这很酷,尽管问题在于 rust 确实限制了我可以从 wasm 实际返回的内容。例如。我想返回一个标记列表,但 rust 根本不允许返回向量(即使它们的行为与 JS 数组非常相似)。所以目前我的代码是通过 serd 序列化的,因此无论如何都要复制。
    猜你喜欢
    • 2020-09-11
    • 1970-01-01
    • 2022-08-15
    • 2021-03-22
    • 2021-01-01
    • 2022-01-11
    • 2020-06-15
    • 2019-03-17
    • 2020-05-03
    相关资源
    最近更新 更多