golang字节码编译脚本语言插件库tengo的使用
Golang字节码编译脚本语言插件库Tengo的使用
Tengo语言简介
Tengo是一种小型、动态、快速、安全的Go脚本语言。它之所以快速且安全,是因为它作为字节码在基于栈的虚拟机上编译/执行,该虚拟机是用原生Go编写的。
/* Tengo语言示例 */
fmt := import("fmt")
each := func(seq, fn) {
for x in seq { fn(x) }
}
sum := func(init, seq) {
each(seq, func(x) { init += x })
return init
}
fmt.println(sum(0, [1, 2, 3])) // "6"
fmt.println(sum("", [1, 2, 3])) // "123"
主要特性
- 简单且高度可读的语法
- 带有类型强制的动态类型
- 高阶函数和闭包
- 不可变值
- 安全嵌入和可扩展
- 编译器/运行时使用原生Go编写(无外部依赖或cgo)
- 可作为独立语言/REPL执行
- 使用场景:规则引擎、状态机、数据管道、转译器
性能基准
语言/实现 | fib(35) | fibt(35) | 类型 |
---|---|---|---|
Tengo | 2,315ms | 3ms | VM |
go-lua | 4,028ms | 3ms | VM |
GopherLua | 4,409ms | 3ms | VM |
goja | 5,194ms | 4ms | VM |
starlark-go | 6,954ms | 3ms | 解释器 |
gpython | 11,324ms | 4ms | 解释器 |
Yaegi | 11,715ms | 10ms | 解释器 |
otto | 48,539ms | 6ms | 解释器 |
Anko | 52,821ms | 6ms | 解释器 |
Go | 47ms | 2ms | 原生 |
Lua | 756ms | 2ms | 原生 |
Python | 1,907ms | 14ms | 原生 |
快速开始
安装Tengo库:
go get github.com/d5/tengo/v2
基础使用示例
以下是一个简单的Go示例代码,演示如何编译/运行Tengo脚本代码并传递输入/输出值:
package main
import (
"context"
"fmt"
"github.com/d5/tengo/v2"
)
func main() {
// 创建新的Script实例
script := tengo.NewScript([]byte(
`each := func(seq, fn) {
for x in seq { fn(x) }
}
sum := 0
mul := 1
each([a, b, c, d], func(x) {
sum += x
mul *= x
})`))
// 设置值
_ = script.Add("a", 1)
_ = script.Add("b", 9)
_ = script.Add("c", 8)
_ = script.Add("d", 4)
// 运行脚本
compiled, err := script.RunContext(context.Background())
if err != nil {
panic(err)
}
// 获取值
sum := compiled.Get("sum")
mul := compiled.Get("mul")
fmt.Println(sum, mul) // "22 288"
}
简单表达式求值
如果你只需要计算一个简单的表达式,可以使用Eval
函数:
res, err := tengo.Eval(ctx,
`input ? "success" : "fail"`,
map[string]interface{}{"input": 1})
if err != nil {
panic(err)
}
fmt.Println(res) // "success"
参考资料
- 语言语法
- 对象类型
- 运行时类型和运算符
- 内置函数
- 互操作性
- Tengo CLI
- 标准库
- 语法高亮支持:VSCode、Atom、Vim
更多关于golang字节码编译脚本语言插件库tengo的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang字节码编译脚本语言插件库tengo的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Tengo: Golang 字节码编译脚本语言插件库
Tengo 是一个用 Go 编写的轻量级、可嵌入的脚本语言,它编译为字节码并在虚拟机上运行。Tengo 的设计目标是简单、高效且易于集成到 Go 应用程序中。
主要特性
- 轻量级且快速
- 动态类型
- 类 C 语法
- 可扩展性
- 内存安全
- 支持闭包
- 编译为字节码
基本用法
安装
go get github.com/d5/tengo/v2
简单示例
package main
import (
"fmt"
"github.com/d5/tengo/v2"
)
func main() {
// 创建脚本
script := tengo.NewScript([]byte(`
// Tengo 代码
text := "Hello, Tengo!"
number := 42
result := text + " " + number
`))
// 运行脚本
compiled, err := script.Run()
if err != nil {
panic(err)
}
// 获取结果
result := compiled.Get("result")
fmt.Println(result.String()) // 输出: Hello, Tengo! 42
}
高级功能
1. 调用 Go 函数
package main
import (
"fmt"
"github.com/d5/tengo/v2"
)
func main() {
script := tengo.NewScript([]byte(`
// 调用 Go 函数
greet("Tengo")
`))
// 定义 Go 函数
greet := tengo.UserFunction{
Name: "greet",
Value: func(args ...tengo.Object) (tengo.Object, error) {
name := args[0].(*tengo.String).Value
return &tengo.String{Value: fmt.Sprintf("Hello, %s!", name)}, nil
},
}
// 添加函数到脚本
_ = script.Add("greet", &greet)
compiled, err := script.Run()
if err != nil {
panic(err)
}
fmt.Println(compiled.Get("greet").String())
}
2. 使用模块
package main
import (
"fmt"
"github.com/d5/tengo/v2"
"github.com/d5/tengo/v2/stdlib"
)
func main() {
script := tengo.NewScript([]byte(`
math := import("math")
sqrt := math.sqrt
result := sqrt(16)
`))
// 添加标准库模块
modules := stdlib.GetModuleMap("math")
script.SetImports(modules)
compiled, err := script.Run()
if err != nil {
panic(err)
}
fmt.Println(compiled.Get("result").String()) // 输出: 4
}
3. 错误处理
package main
import (
"fmt"
"github.com/d5/tengo/v2"
)
func main() {
script := tengo.NewScript([]byte(`
// 故意制造错误
undefinedFunc()
`))
_, err := script.Run()
if err != nil {
// 获取运行时错误
if runtimeErr, ok := err.(*tengo.RuntimeError); ok {
fmt.Printf("Runtime error: %s at line %d\n",
runtimeErr.Message,
runtimeErr.Traceback[0].Line)
} else {
fmt.Printf("Compile error: %v\n", err)
}
}
}
性能优化技巧
- 复用脚本对象:对于频繁执行的脚本,可以预编译并复用
script := tengo.NewScript([]byte(`...`))
compiled, err := script.Compile()
if err != nil {
panic(err)
}
// 多次执行
for i := 0; i < 100; i++ {
_, err := compiled.Run()
if err != nil {
panic(err)
}
}
- 限制执行时间:防止无限循环
script := tengo.NewScript([]byte(`while true {}`))
script.SetMaxAllocs(10000) // 限制分配次数
_, err := script.Run()
if err != nil {
fmt.Println("Execution stopped:", err)
}
实际应用场景
- 配置解析:动态解析用户提供的配置
- 规则引擎:执行用户定义的业务规则
- 插件系统:允许用户扩展应用程序功能
- 模板引擎:动态生成内容
- 教育工具:教授编程概念
总结
Tengo 为 Go 应用程序提供了一个强大而灵活的脚本解决方案。它的轻量级设计和简单 API 使得集成变得非常容易,同时提供了足够的表达能力来处理复杂的脚本需求。无论是简单的表达式求值还是复杂的业务逻辑,Tengo 都能胜任。
更多高级功能和详细文档可以参考 Tengo 官方 GitHub 仓库。