背景
go 是一种静态语言,运行需要先编译。实际我们在使用过程中,有时候希望 go 能够像脚步语言一样执行一些动态的命令,这种功能至少有以下的好处:
- 学习使用,作为一种 repl 工具验证语法
- 快速验证某个包的功能,或者某种远程资源内容
- 作为工程的嵌入代码,提供灵活性,比如作为一个爬虫项目,抓取脚本的改动肯定不希望整个工程都要重新编译
- 做为测试脚本使用,脚本语言开发快,验证快,比较适合开发一些测试工具
开源项目
工具 | 语法 | 作为 repl 可用性 | 作为嵌入脚本可用性 | 原理 | 备注 |
---|---|---|---|---|---|
直接 go run | golang | 很低 | 中 | go run | 可以在go 语言文件上面加 env 标识,同时 对 go run 封装一下, 比如这样,可以动态获取包 |
gop | golang like | 高(v0.7) | 高 | 两种模式,bytecode 模式使用 VM 实现,还有一种模式使用代码生成 + go run | v0.7 支持 repl,master 已经删除 |
tengo | golang like | 高 | 高 | VM | 官方 bench 表示性能在同类中很高 |
go-lua | lua | 高 | 高 | VM | Shopify 实现 |
gopher-lua | lua | 高 | 很高 | VM | 文档丰富,扩展方便 |
goja | ECMAScript/JavaScript | 高 | 中 | VM | - |
starlark-go | starlark(python 子集) | 高 | 高 | VM | Google 出品,语法是 python 子集,学习成本低且使用舒适 |
gpython | python | 中 | 中 | Interpreter | 成熟度不高 |
yaegi | golang | 高 | 高 | Interpreter | traefik 出品 |
go-pry | golang | 中 | 很低 | 代码生成 + Interpreter | 只能用于做语法验证工具, 交互比较友好, 不能用于内嵌 |
otto | JavaScript | 中 | 高 | Interpreter | 项目比较活跃 |
anko | golang like | 中 | 中 | Interpreter | - |
gore | golang like | 高 | 低 | 代码生成 + go run | 作为 repl 工具还可以,支持代码提示 |
gomacro | golang like | 很高 | 中 | 代码生成 + Interpreter | 作为 repl 工具的最佳选择, 支持 import 第三方包, 功能非常健全,这个 go jupyter kernel 就是基于 gomacro |
说明
- 工具整理于 202110
- 作为嵌入脚本,都要考虑能否使用 go 语言自带包或者开发第三方库来丰富他的功能,这点 gopher-lua 比较方便
- 作为嵌入脚本,要降低使用成本,使用已经存在的、简单的语言的优势比较明显,比如 lua、starlark
- 能否动态 import 第三方库对于作为 repl 使用是一个很重要的功能,这点只有 gomacro 支持
- 可用性得分档为 很低/低/中/高/很高
- 主要有两种实现,VM 或者 Interpreter,一般来说 VM 实现的性能会高不少【基于 vm 有一些优化策略】,不过并不绝对。比如 starlark-go 文档中认为用 go 实现 vm 效率并没有优势,但是目前 starlark-go 的实现也是 vm (docs 比较陈旧,代码已经是 vm 实现了)