WebAssembly 和 Go 入门
WebAssembly (Wasm) 是一种低级二进制指令格式,在浏览器中以接近原生的速度运行。结合 Go 语言 (Golang),您将获得一个用于创建高性能 Web 应用程序的强大工具。Go 可以编译为 WebAssembly,从而允许将复杂的计算、算法甚至游戏直接移植到浏览器中,而无需牺牲性能。
在本文中,我们将介绍如何配置环境、编写一个简单的 Go 模块、将其编译为 Wasm 并与 JavaScript 集成。您将了解关键包、限制和最佳实践。
配置 Go 编译为 Wasm 的环境
安装 Go 和 WebAssembly 依赖项
首先,确保您已安装 Go 1.11 或更高版本(建议使用 1.21+)。WebAssembly 开箱即用。编译时使用环境变量 GOOS=wasm GOARCH=wasm。
您还需要 Go 附带的 wasm_exec.js 支持文件。将其复制到项目根目录:
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .项目结构
创建一个简单的结构:
my-wasm-app/├── main.go├── wasm_exec.js├── index.html└── main.wasm (编译后创建)为 WebAssembly 编写 Go 模块
简单示例:加法函数
创建包含以下内容的 main.go 文件:
package main
import ( "syscall/js")
func add(this js.Value, args []js.Value) interface{} { if len(args) < 2 { return 0 } a := args[0].Int() b := args[1].Int() return a + b}
func main() { c := make(chan struct{}, 0)
js.Global().Set("goAdd", js.FuncOf(add))
<-c}这里我们使用 syscall/js 包与 JavaScript 交互。add 函数接受两个参数并返回它们的和。通道 c 阻止程序退出,使模块保持活动状态。
编译为 Wasm
执行命令:
GOOS=wasm GOARCH=wasm go build -o main.wasm main.go结果将生成一个 main.wasm 文件,对于这个简单示例,大小约为 1-2 MB。在生产环境中,使用 -ldflags="-s -w" 标志来减小体积。
与 HTML 和 JavaScript 集成
创建 HTML 页面
创建 index.html 文件:
<!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8"> <title>Go + WebAssembly</title> <script src="wasm_exec.js"></script></head><body> <h2>浏览器中的 Go 计算器</h2> <input type="number" id="num1" value="5"> <input type="number" id="num2" value="10"> <button onclick="calculate()">相加</button> <p>结果: <span id="result">0</span></p>
<script> const go = new Go(); WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject) .then((result) => { go.run(result.instance); console.log("WebAssembly 模块已加载"); });
function calculate() { const a = parseInt(document.getElementById('num1').value); const b = parseInt(document.getElementById('num2').value); const sum = goAdd(a, b); document.getElementById('result').innerText = sum; } </script></body></html>请注意:由于在 Go 代码中调用了 js.Global().Set("goAdd", ...),函数 goAdd 变成了全局函数。