ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

wasm-bindgen `[wasm_bindgen(inspectable)]` 属性指南:为 Rust 导出结构体生成 `toJSON` / `toString` 可检查实现

wasm-bindgen `[wasm_bindgen(inspectable)]` 属性指南:为 Rust 导出结构体生成 `toJSON` / `toString` 可检查实现 开发工具【免费下载链接】wasm-bindgenFacilitating high-level interactions between Wasm modules and JavaScript项目地址https://gitcode.com/gh_mirrors/wa/wasm-bindgen点击查看免费下载导读inspectable是 wasm-bindgen 提供在 Rust 导出结构体struct上的属性用于自动生成toJSON与toString两个 JavaScript 方法使导出类不再只暴露一个ptr属性而是可以把所有可读字段完整序列化出来便于日志输出、调试与数据交换。本文以 官方参考文档 为骨架结合仓库中的宏解析parser.rs、JS 代码生成js/mod.rs与端到端测试classes.rs、classes.js深入讲解其行为、覆盖范围、自定义覆盖方式及 Node.js 下的特殊支持读完你可以直接在项目里为导出结构体启用并微调该特性。默认行为为什么导出类“看不见”字段默认情况下从 Rust 导出的结构体会被编译成 JavaScript 类类实例上只有一个ptr属性实际持有指向 Wasm 线性内存中 Rust 对象指针的__wbg_ptr。其他所有字段虽然会生成对应的 getter 访问器但 getter 不会被JSON.stringify、toJSON或console.log枚举出来——也就是说直接序列化实例时看不到任何业务字段。该行为可以从代码生成端得到印证js/mod.rs 的类导出逻辑 中明确指出只有当class.is_inspectable为真时才生成toJSON与toString否则类只有ptr相关成员。测试 classes.js 也验证了这一点// 未加 inspectable 的类没有生成 toJSON/toString assert.strictEqual(not_inspectable.toJSON, undefined); assert.strictEqual(not_inspectable.toString(), [object Object]); // Node 下 console.log 只显示 __wbg_ptr // 形如NotInspectable { __wbg_ptr: 123456 }使用inspectable一行属性获得完整序列化在导出结构体的#[wasm_bindgen(...)]属性列表中加入inspectable即可。官方文档给出的完整示例#[wasm_bindgen(inspectable)] pub struct Baz { pub field: i32, private: i32, // 私有字段不会被导出除非单独提供 getter } #[wasm_bindgen] impl Baz { #[wasm_bindgen(constructor)] pub fn new(field: i32) - Baz { Baz { field, private: 13 } } }编译后在 JavaScript 中可以得到如下行为const obj new Baz(3); assert.deepStrictEqual(obj.toJSON(), { field: 3 }); // 只包含可读字段 obj.field 4; assert.strictEqual(obj.toString(), {field:4}); // toString 内部调用 toJSON属性解析链路inspectable在宏解析阶段被登记为合法属性parser.rs(inspectable, false, Inspectable(Span))随后通过attrs.inspectable().is_some()读取parser.rs并随结构体元数据一路传递到 CLI 侧最终存入 nonstandard.rs 中的AuxStruct::is_inspectable再由 js/mod.rs 生成 JS 代码。生成代码的形态对普通命名结构体CLI 生成的toJSON形如toJSON() { return { field: this.field, // 所有可读字段public 字段 公开 getter都会被收集 }; } toString() { return JSON.stringify(this); }代码生成逻辑见 js/mod.rs生成规则要点**可读字段集合readable_properties**由两部分构成pub字段以及通过 getter 暴露的属性在收集公开 getter 时会跳过符号键Symbol字段因为toJSON只能收集字符串键属性js/mod.rs。字段名如果是合法标识符则用field: this.field的形式若不是如元组结构体的0、1则使用带引号键0: this[0]避免生成非法 JavaScriptjs/mod.rs。同时会向.d.ts声明文件写入对应类型声明toJSON(): Object;与toString(): string;并附带注释说明语义js/mod.rs。完整声明示例可查看参考测试的 inspectable.d.ts。元组结构体编号字段的序列化inspectable同样适用于元组结构体。参考测试 inspectable.rs 中的Pair(pub u32, pub i32)在--targetnodejs下生成的 inspectable.js 为toJSON() { return { 0: this[0], 1: this[1], }; } toString() { return JSON.stringify(this); }对应的端到端测试 classes.js 验证其行为const tuple wasm.InspectableTuple.new(1, -2); // 元组字段以属性 0、1 暴露 assert.deepStrictEqual(tuple.toJSON(), { 0: 1, 1: -2 }); assert.strictEqual(tuple.toString(), {0:1,1:-2});这一行为经过一次修复早期版本为元组结构体生成this.0这种非法的 JavaScript 访问形式现已改为this[0]见 CHANGELOG.md本仓库中的生成代码正是修正后的实现。覆盖生成的toJSON/toString如果你希望自定义序列化输出可以用js_name属性覆盖。注意生成的toString内部调用toJSON因此覆盖toJSON会连带影响toString的输出。官方文档示例#[wasm_bindgen] impl Baz { #[wasm_bindgen(js_name toJSON)] pub fn to_json(self) - i32 { self.field } #[wasm_bindgen(js_name toString)] pub fn to_string(self) - String { format!(Baz: {}, self.field) } }仓库测试 classes.rs 的OverriddenInspectable与对应 JS 断言 classes.js 完整覆盖了该场景assert.deepStrictEqual(overridden_inspectable.toJSON(), JSON was overwritten); assert.strictEqual(overridden_inspectable.toString(), string was overwritten);浏览器环境中的console.log限制需要注意即使加了inspectable浏览器里console.log的输出依然不会变仍然只显示ptr字段。这是因为浏览器对console.log的处理不通过toJSON/toString。官方文档建议在这种场景下调用toJSON()或JSON.stringify(obj)来辅助日志与调试。Node.js 不受此限制详见下一节。Node.js 目标下的增强[util.inspect.custom]当以nodejs目标编译时生成器还会额外提供一个[util.inspect.custom]实现内部调用toJSON。由于 Node.js 的console.log及其同类函数如util.inspect、console.dir会优先使用该自定义检查器因此可以像原生 JS 对象一样打印出全部可读字段。实现位于 js/mod.rs生成器从util模块导入inspect然后生成[inspect.custom]() { return Object.assign(Object.create({constructor: this.constructor}), this.toJSON()); }这里通过Object.create({constructor: this.constructor})保留类名使输出形如Point { x: 1, y: 2 }与普通 JavaScript 类的打印风格一致。参考测试生成的 inspectable.js 与 classes.js 的验证 都体现了这一点// Inspectable 类在 Node.js 下 console.log 会显示所有可读字段 assert(console_log_to_string(inspectable).endsWith({ a: ${inspectable.a} }));注意该文件头部的const { inspect } require(util);正是由 js/mod.rs 的模块导入逻辑 生成的对应输出可见 inspectable.js。调试建议与综合示例综合以上内容一个实用模式是use wasm_bindgen::prelude::*; #[wasm_bindgen(inspectable)] pub struct Point { pub x: u32, pub y: u32, } #[wasm_bindgen] impl Point { #[wasm_bindgen(constructor)] pub fn new(x: u32, y: u32) - Point { Point { x, y } } }在 Node.js 中const p new Point(3, 4); console.log(p); // Point { x: 3, y: 4 } —— 借助 util.inspect.custom console.log(JSON.stringify(p)); // {x:3,y:4} —— 借助 toJSON p.x 5; console.log(p.toString()); // {x:5,y:4} —— toString 内部调用 toJSON而在浏览器控制台中console.log(p)仍只显示ptr属性此时应显式调用p.toJSON()或JSON.stringify(p)查看字段内容。小结能力默认结构体inspectable结构体实例字段仅ptr__wbg_ptr全部可读字段pub字段 公开 gettertoJSON()无自动生成返回可读字段对象toString()[object Object]自动生成JSON.stringify(this)结果浏览器console.log仅显示ptr仍仅显示ptr建议用toJSON()/JSON.stringifyNode.jsconsole.log仅显示__wbg_ptr显示所有可读字段经[util.inspect.custom]自定义输出—用js_name toJSON/js_name toString覆盖inspectable属性在 wasm-bindgen 0.12 时代引入见 CHANGELOG.md至今仍是导出结构体日志与序列化方案的首选工具。想要深入了解完整属性列表可查阅 on-rust-exports 目录索引或直接阅读 官方参考文档 获取最权威的说明。赞分享开发工具【免费下载链接】wasm-bindgenFacilitating high-level interactions between Wasm modules and JavaScript项目地址https://gitcode.com/gh_mirrors/wa/wasm-bindgen点击查看免费下载相关推荐TypeGraphQL与Rust集成使用wasm-bindgen实现高性能组件TypeGraphQL与Rust集成使用wasm bindgen实现高性能组件 技术背景与集成价值 TypeGraphQL作为TypeScript优先的Gra后端GraphQLAPI设计ik_llama.cpp 函数调用Function Calling支持全解析Kimi-K2 原生 Token 格式、Qwen3 XML 与 DeepSeek R1 多格式统一解析ik_llama.cpp 函数调用Function Calling支持全解析Kimi K2 原生 Token 格式、Qwen3 XML 与 DeepSee开发工具Nitro Runtime Config 完全指南定义配置、环境变量覆盖与运行时读取Nitro Runtime Config 完全指南定义配置、环境变量覆盖与运行时读取 NitroNext Generation Server Toolkit开发工具上一篇【亲测免费】 探索高精度棋盘格角点检测Matlab算法详解下一篇WeSpeaker-ResNet34-LM-MLX模型训练与微调定制化说话人识别系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表