[gomacro](https://github.com/cosmos72/gomacro)
是一个近乎完整的 Go 解释器,用纯 Go 实现,它同时提供交互式 REPL
和脚本模式,并且在运行时不需要 Go 工具链(除了一些非常特殊的场景:在运行时导入第三方包)。它在 Go 标准库之外有两个依赖项:github.com/peterh/liner
和 golang.org/x/tools/go/packages
。
REPL
是 Read-Eval-Print Loop
的缩写,是一种简单的,交互式的编程环境,其中 REPL 分别指:
- Read:获得用户输入
- Eval:对输入求值
- Print:打印、输出求值的结果
- Loop:循环,可以不断地重复 Read-Eval-Print
REPL 对于学习一门新的编程语言非常有帮助,你可以在这个交互环境里面通过输出快速验证你的理解是不是正确。比如我们最常使用的 Python 自带了一个这样的编程环境:
➜ ~ python3
Python 3.8.9 (default, Mar 30 2022, 13:51:16)
[Clang 13.1.6 (clang-1316.0.21.2.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 1
>>> a + 2
3
>>> print(a - 2)
-1
>>>
功能
Gomacro 就是这样一个针对 Go 语言的一个 REPL 工具,它可以被用来:
- 一个独立的可执行文件,具有交互式
Go REPL
、行编辑和代码补全功能:只需在命令行中运行gomacro
,然后输入 Go 代码即可。
$ gomacro
[greeting message...]
gomacro> import "fmt"
gomacro> fmt.Println("hello, world!")
hello, world!
14 // int
// error
gomacro>
- 只需要按下 TAB 键就可以自动提示,再按 TAB 键可以循环完成可能的内容。行编辑主要遵循 Emacs。
Ctrl+A
或Home
跳到行首,Ctrl+E
或End
跳到行尾,Ald+D
删除从光标开始的单词...... - 一个试验的 Go 泛型工具
- Go 源码 debug 工具
- 一个交互式工具,如果你使用已编译的 Go 与科学库(物理学、生物信息学、统计学......),你可以从
gomacro REPL
导入相同的库(在 Linux 和 Mac OS X 上立即生效,在其他平台上需要重新启动),交互式地调用它们,检查结果,将它们反馈给其他函数/库,所有这些都在一个会话中完成。导入的库将被编译,而不是解释,所以它们将和编译后的 Go 一样快。 - 只需几行代码即可将
Eval()
和脚本功能添加到你的 Go 程序中:
package main
import (
"fmt"
"reflect"
"github.com/cosmos72/gomacro/fast"
)
func RunGomacro(toeval string) reflect.Value {
interp := fast.New()
vals, _ := interp.Eval(toeval)
// for simplicity, only use the first returned value
return vals[0].ReflectValue()
}
func main() {
fmt.Println(RunGomacro("1+1"))
}
- 一种在没有 Go 编译器的情况下即时执行 Go 源代码的方法:你可以运行
gomacro FILENAME.go
。或者你可以在 Go 源文件的开头插入一行#!/usr/bin/env gomacro
,然后使用chmod +x FILENAME.go
将该文件标记为可执行文件,最后使用./FILENAME.go
即可执行它(仅适用于在类 Unix 系统上:Linux、*BSD、Mac OS X ...) - Go 代码生成工具:
gomacro
最初是作为向 Go 添加类似 Lisp 的宏的实验开始的,它们对于简化代码生成非常有用。宏是普通的 Go 函数,其特殊之处仅在于一个方面:在编译代码之前执行,其输入输出为代码
安装
需要 Go 1.13+ 版本,Gomacro
是纯 Go,理论上它应该可以在 Go 编译器支持的任何平台上运行。以下组合经过测试并已知有效:
- Linux: amd64,386, arm64, arm, mips, ppc64le
- Mac OS X: amd64,386 (386 binaries running on amd64 system)
- Windows: amd64,386
- FreeBSD: amd64,386
- Android: arm64, arm
执行下面的命令即可安装:
go get -u github.com/cosmos72/gomacro
使用
如果你在 Linux 或 Mac OS X 上运行 gomacro
,那么 import 就可以工作了:它会自动下载、编译和导入一个包,如下所示:
$ gomacro
[greeting message...]
gomacro> import ( "gonum.org/v1/floats"; "gonum.org/v1/plot" )
// debug: running "go get gonum.org/v1/gonum/floats gonum.org/v1/plot" ...
go: downloading gonum.org/v1/plot v0.11.0
[... more messages from go toolchain ...]
// debug: running "go mod tidy" ...
go: downloading github.com/go-fonts/latin-modern v0.2.0
go: downloading rsc.io/pdf v0.1.1
go: downloading github.com/go-fonts/dejavu v0.1.0
// debug: compiling plugin "/home/max/go/src/gomacro.imports/gomacro_pid_187824/import_1" ...
gomacro> plot.New()
&{...} // *gonum.org/v1/plot.Plot
注意:在内部,gomacro
将编译和加载一个 Go 插件,其中包含 import ( ... )
中列出的所有包的导出声明。
命令 go mod tidy
在编译插件之前会自动执行,它会尝试解决由于直接导入或间接导入同一包的不同版本而导致的任何版本冲突(即作为必需的依赖项)。
Go 插件目前仅在 Linux 和 Mac OS X 上受支持。
从 2.6 版开始,gomacro
还集成了调试器。输入方式有以下三种:
- 在解释代码运行时按
CTRL+C
- 在提示符下输入
: debug STATEMENT-OR-FUNCTION-CALL
- 在代码中添加语句(表达式不够)
"break"
或_ ="break"
,然后正常执行
在所有情况下,执行都将暂停,你将收到一个 debug>
提示符,该提示符接受以下命令:step
、next
、finish
、continue
、env [NAME]
、inspect EXPR
、list
、print EXPR-OR-STATEMENT
。
总体上的体验就是一个支持基本功能的 REPL,支持 Tab 自动补全(例如输入 fmt.Print
按 Tab 会在 fmt.Print
、fmt.Printf
和 fmt.Println
之前切换)、调试和简单的查看函数签名。gomacro
对于基本的快速验证代码运行结果是够的。
Git 仓库:github.com/cosmos72/go…