golang中的eval,goeval,govaluate

在解释型语言中基本都提供了 eval() 函数,将字符串当做代码来执行。而golang并没有提供此方法。我在编写计算器桌面应用的时候发现,必须要有 eval 函数才能实现。

PaulXu-cn/goeval

https://github.com/PaulXu-cn/goeval

在临时目录os.TempDir()下创建随机目录,然后创建main.go文件,填充go源码,运行完然后将其删掉,获取stdout信息。

go 复制代码
// github.com/PaulXu-cn/goeval
func Eval(defineCode string, code string, imports ...string) (re []byte, err error)

第一个参数填入自定义的变量/函数/结构体等。

第二个参数是代码字符串。

第三个参数是本代码依赖了哪些包,可以是标准库,也可以是第三方包。

go 复制代码
func t11() {
	res, err := goeval.Eval("", "fmt.Println(3*(1+2))", "fmt")
	fmt.Println(string(res), err)
}

func t12() {
	res, err := goeval.Eval("", `line := "3*(1+1)"
	expr, _ := govaluate.NewEvaluableExpression(line)
	result, _ := expr.Evaluate(nil)
	fmt.Println(result)`, "fmt", "github.com/Knetic/govaluate")
	fmt.Println(string(res), err)
}

代码格式化 :因为Go有些地方对format有要求,比如定义函数的时候左大括号不能换行,使用go/format来进行格式化。

go.mod 的处理 :如果引入了标准库以外的包,就需要初始化go.mod文件,但是PaulXu-cn/goeval没有这个操作,代码也能正常运行,主要是因为,这是在当前项目下运行一个tmp项目下的main.go,于是go命令会检查当前项目下的go.mod,而不是tmp项目下的go.mod,而在当前项目下我实际上也在使用github.com/Knetic/govaluate包,这就导致可以正常运行,但是,如果 eval 代码串中引入的包,在当前项目下并没有用到,就会报错,这个时候你可以使用下划线语法将其引入。

xtaci/goeval

https://github.com/xtaci/goeval

此项目式借助 go/ast, go/parser解析抽象语法树来实现的。

go 复制代码
func t2() {
	s := evalhandle.NewScope()
	s.Set("print", fmt.Println)
	fmt.Println(s.Eval(`count := 0`))
	fmt.Println(s.Eval(`for i:=0; i<10; i++ { 
			count=count+i
		}`))
	fmt.Println(s.Eval(`print(count)`))
}
Knetic/govaluate

https://github.com/Knetic/govaluate

计算一个表达式的值并得到返回结果。

go 复制代码
func t3() {
	line := "3*(1+2)"
	expr, _ := govaluate.NewEvaluableExpression(line)
	result, _ := expr.Evaluate(nil)
	fmt.Println(result) // 9
}

最终使用了govaluate完成了计算器的开发。

相关推荐
孟陬6 分钟前
技术周刊#158:ChatGPT 智能 UI 底层原理、个人智能体协议正式发布、一条 POST 请求即可锁死 Next.js 服务
人工智能·后端·全栈
LabVIEW开发9 分钟前
LabVIEW 局部变量与数据流:这道 CLAD 题为什么答案是 Undefined
java·开发语言·labview
路溪非溪12 分钟前
C++标准库之智能指针
linux·开发语言·c++
小蒜学长21 分钟前
基于SpringBoot+Vue的云南地区扶贫助农系统的设计与实现(代码+数据库+LW)
java·vue.js·spring boot·后端·乡村振兴
码剑客26 分钟前
Gin+GORM+Redis 项目开发常见性能坑汇总(Go后端避坑指南)
redis·后端·golang·gin
衍生星球1 小时前
【Java 语言】— 面向对象:构造方法(无参、有参构造)
java·开发语言
java_nnnn1 小时前
Spring Boot 配置文件详解:从基础语法到 YAML 配置
spring boot·后端·github
SimonKing1 小时前
素笺( local-notes)全面优化,新增功能体验不一样的笔记
java·后端·程序员
FungLeo1 小时前
成为全栈·Go 后端篇·换后端不改前端:四个客户端如何做兼容回归
flutter·golang·go·成为全栈·兼容测试·taro 小程序
yuniko-n1 小时前
【JVM】对象内存布局
java·开发语言·jvm