Go粉有福了,想让Go跑到超小的地方?比如Arduino、树莓派Pico,甚至浏览器里的WebAssem)bly?那你一定得认识一下TinyGo。今天咱们就来聊聊这款“Go编译器”,它到底是个什么玩意儿,有哪些黑科技,能不能真香。
什么是 TinyGo
简单说,TinyGo就是一个面向“小内存、小芯片”的Go编译器。它把Go语言重用官方的库、加上LLVM后端,专门把Go编译成适合微控制器(MCU)、WASM/WASI、以及一些命令行工具的可执行代码。比起官方的gc编译器,它更轻,更小,更灵活。
解决了哪些痛点
平时写Go,头痛的事儿:
-
• 二进制太大:官方编译器生成的可执行文件动辄几MB,MCU根本装不下。
-
• 没有嵌入式支持:想在Arduino、STM32上跑Go?官方压根不支持。
-
• WASM性能堪忧:Go的官方WASM工具链太臃肿,启动慢。
TinyGo上场后,上述问题一扫而空:
-
• 二进制可裁剪到几十KB,GC更轻量;
-
• 一套代码,几乎无需改动就能跑在Arduino、Adafruit ItsyBitsy和更多94种MCU;
-
• 编译WASM/WASI时体积小、启动快,还能跟Fastly Compute、Fermyon Spin、wazero等无缝对接。
动手例子:从嵌入式到WebAssembly
-
• 嵌入式“闪灯”示例 这段在Arduino Uno和It’syBitsy M0上都能闪LED的代码,只要切换目标就行:
package main
import (
"machine"
"time"
)
func main(){
led := machine.LED
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
for{
led.Low()
time.Sleep(time.Millisecond*500)
led.High()
time.Sleep(time.Millisecond*500)
}
}编译并刷机:
tinygo flash -target arduino examples/blinky1 -
• WebAssembly“小函数”示例 想写一个加法函数,给浏览器或WASI调用?也不过如此:
package main
//go:wasmexport add
func add(x, y uint32) uint32 {
return x + y
}编译WASI版:
tinygo build -o add.wasm -target=wasip1 -buildmode=c-shared add.go或者用Go 1.24+的环境变量方式:
GOOS=wasm GOARCH=wasip1 tinygo build -o add.wasm -buildmode=c-shared add.go
安装与支持平台
TinyGo也懒人友好了,支持多种安装方式:
-
• Homebrew(macOS/Linux)
-
• Scoop(Windows)
-
• Docker镜像
-
• Nix包管理
支持的平台一览:
|
类型 |
平台/板卡 |
|
嵌入式 |
Arduino、Adafruit、STM32、RP2040…共94+ |
|
WebAssembly |
浏览器WASM、WASI |
|
OS |
Linux、macOS、Windows |
优缺点一览
咱们来张表,看得更直观:
|
优点 |
缺点 |
|
二进制体积小,启动快 |
不支持Go所有特性(反射、unsafe部分) |
|
支持主流MCU和WASM/WASI |
标准库支持度有限 |
|
直接集成LLVM,优化更灵活 |
调试体验比官方gc差点 |
|
CGo调用开销与普通函数调用无异 |
多线程/协程极限场景下性能不如gc |
总结
TinyGo就像给Go装备了隐形战斗机翅膀,让它能在资源极度受限的环境里跑得飞快。无论是做IoT项目的嵌入式开发,还是在边缘计算里用WASM部署函数,都能轻松胜任。当然,它还不是“All in one”——在一些极端场景下,特性支持和调试体验还得继续打磨。总体来说,如果你想把Go带到更小、更轻、更快的世界,TinyGo绝对是很好玩的开源利器。
项目地址:https://github.com/tinygo-org/tinygo