🐯 猫头虎博主在此,带大家一起探索Go语言的新天地!在本篇博客中,我们将深入研究Go 1.21版本如何通过WASI syscall API为WebAssembly提供支持。准备好,一起在Go的世界中冲浪吧!不要忘记,搜索“Go WASI”可以发现更多精彩内容!
自从Go 1.11引入对WebAssembly的支持以来,Go语言与Wasm的结合愈发紧密。如今,Go 1.21版在这一领域又迈出了新步伐,引入了针对WASI preview 1 syscall API的新端口wasip1
。让我们一探究竟,看看Go如何利用WASI,进一步扩展其WebAssembly的能力。
WebAssembly(Wasm)最初为Web设计,是一种二进制指令格式,能够让开发者在浏览器中以接近原生速度运行高性能、低层次的代码。Go在1.11版本首次加入了对Wasm的编译支持,通过js/wasm
端口实现。
WASI为Wasm可执行文件定义了一个syscall API,允许它们与文件系统、系统时钟、随机数据工具等系统资源进行交互。WASI的最新版本被称为wasi_snapshot_preview1
,Go中相应的GOOS
值为wasip1
。随着API的不断发展,Go未来可能会添加新的GOOS
以支持它们。
要在Go中使用WASI,首先确保安装了至少1.21版本的Go。在本示例中,我们使用Wasmtime作为宿主运行我们的二进制文件。首先,我们有一个简单的main.go
:
package main
import "fmt"
func main() {
fmt.Println("Hello world!")
}
我们可以使用以下命令为wasip1
构建它:
$ GOOS=wasip1 GOARCH=wasm go build -o main.wasm main.go
然后,使用wasmtime
执行生成的文件:
$ wasmtime main.wasm
Hello world!
除了构建和运行二进制文件外,我们还希望能够直接运行go test
。通过将misc/wasm
目录添加到您的PATH
中,可以使用所选的Wasm宿主运行测试。这是通过go test
在PATH
中找到misc/wasm/go_wasip1_wasm_exec
文件时自动执行它来实现的。
$ export PATH=$PATH:$(go env GOROOT)/misc/wasm
$ GOOS=wasip1 GOARCH=wasm go test ./...
Go 1.21还引入了一种新的编译器指令:go:wasmimport
。这使我们能够将对注释函数的调用转换为对宿主模块名称和函数名称指定的函数的调用。例如,wasip1 syscall API定义了random_get
函数,并通过Go标准库中定义的函数包装器暴露给Go标准库。
Wasm是单线程架构,没有并行性。
在Wasm中,wasip1
API缺少对网络套接字的完整实现,这是Go标准库中一些最受欢迎功能的重要组成部分。
wasip1/wasm
端口的添加只是我们希望为Go带来的Wasm能力的开始。请关注相关的议题跟踪器,了解更多关于在Wasm中导出Go函数(go:wasmexport
)、32位端口和未来WASI API兼容性的提案。
如果您正在尝试Wasm和Go并希望做出贡献,请参与进来!Go问题跟踪器跟踪所有正在进行的工作,Gophers Slack上的#webassembly频道是讨论Go和WebAssembly的好地方。
本文被猫头虎的Go生态洞察专栏收录,详情点击这里。我们深入探讨了Go 1.21如何通过新端口wasip1
支持WASI,这是Go在WebAssembly领域的一大步。希望你们喜欢这次的探索旅程!