带字符串的 Rust wasm-bindgen 结构
Rust wasm-bindgen struct with string
我正在尝试导出以下结构:
#[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 的新手,非常感谢您的帮助。
根据 wasm-bindgen#1985,结构的 public 字段必须 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 端设置的内容。
我正在尝试导出以下结构:
#[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 的新手,非常感谢您的帮助。
根据 wasm-bindgen#1985,结构的 public 字段必须 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 端设置的内容。