golang简化Starlark脚本执行与数据转换的插件库starletstarlark-go的使用
Golang简化Starlark脚本执行与数据转换的插件库starlet(starlark-go)的使用
✨ Starlet - 增强Starlark的简单方式
Starlet是另一个针对官方Starlark in Go项目的Go封装库,旨在通过强大的扩展和丰富的封装增强Starlark脚本体验,为在Go应用中嵌入Starlark脚本提供更友好和强大的接口。
主要特性
灵活的机器抽象
Starlet引入了执行Starlark脚本的简化接口,封装了设置和运行脚本的复杂性。Machine
类型作为Starlark运行时环境的全面封装,提供了直观的API来执行Starlark脚本、管理全局变量、加载模块、控制脚本执行流程以及处理脚本输出。
增强的数据转换
Starlet提供了dataconv
包,简化了Go和Starlark类型之间的数据交换。它专注于将Go值转换为Starlark等效值,反之亦然,从而更无缝地将Go的丰富数据类型集成到Starlark脚本中。
扩展库和功能
Starlet包含一组自定义模块和库,扩展了Starlark语言的功能。这些模块涵盖了广泛的用例,如文件操作、HTTP客户端、JSON/CSV处理等,使Starlark脚本更加强大和多功能。
安装
要安装Starlet,请在项目目录下使用以下Go命令:
go get github.com/1set/starlet
要探索Starlet CLI工具的功能,使用以下命令安装:
go install github.com/1set/starlet/cmd/starlet@latest
使用示例
以下是一个完整的Go示例,展示如何使用Starlet执行Starlark脚本并进行数据转换:
package main
import (
"fmt"
"github.com/1set/starlet"
)
func main() {
// 定义带有全局变量和模块的机器
globals := starlet.StringAnyMap{
"greet": func(name string) string {
return fmt.Sprintf("Hello, %s!", name)
},
}
mac := starlet.NewWithNames(globals, []string{"random"}, nil)
// 在机器中运行Starlark脚本
script := `
target = random.choice(["World", "Starlark", "Starlet"])
text = greet(target)
print("Starlark:", text)
`
res, err := mac.RunScript([]byte(script), nil)
// 检查错误和结果
if err != nil {
fmt.Println("Error executing script:", err)
return
}
fmt.Println("Go:", res["text"].(string))
fmt.Println("Modules:", starlet.GetAllBuiltinModuleNames())
}
可能的输出:
Starlark: Hello, Starlet!
Go: Hello, Starlet!
Modules: [atom base64 csv file go_idiomatic hashlib http json log math path random re runtime string struct time]
库概览
Starlet附带了一组扩展标准Starlark库的库:
包 | 描述 |
---|---|
atom | 整数、浮点数和字符串的原子操作 |
base64 | Base64编码和解码函数 |
csv | 解析和写入逗号分隔值(csv)内容 |
file | 与文件系统交互的函数 |
goidiomatic | Starlark的Go惯用函数和值 |
hashlib | Starlark的哈希原语 |
http | Starlark的HTTP客户端和服务器处理程序实现 |
json | 将Starlark值转换为/从JSON字符串的工具 |
log | 在不同严重级别记录消息的功能 |
path | 操作目录和文件路径的函数 |
random | 为各种分布生成随机值的函数 |
re | Starlark的正则表达式函数 |
runtime | 提供Go和应用运行时信息 |
string | 操作字符串的常量和函数 |
贡献
欢迎对Starlet做出贡献。如果您遇到任何问题或有改进建议,请随时提出问题或提交拉取请求。在进行任何重大更改之前,请通过提出问题或认领现有问题来告知我们,以确保没有重复工作。
许可证
Starlet根据MIT许可证授权。
更多关于golang简化Starlark脚本执行与数据转换的插件库starletstarlark-go的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang简化Starlark脚本执行与数据转换的插件库starletstarlark-go的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用starlet简化Starlark脚本执行与数据转换
Starlark是一种类似Python的配置语言,常用于构建系统如Bazel。在Go生态中,starlark-go
是官方实现,而starlet
是基于它构建的简化插件库,提供了更友好的API和实用功能。
starlet核心功能
starlet
主要提供以下便利功能:
- 简化脚本执行流程
- 自动类型转换(Go ↔ Starlark)
- 预置常用模块(math, time, json等)
- 错误处理优化
安装
go get github.com/1set/starlet
基础使用示例
package main
import (
"fmt"
"github.com/1set/starlet"
)
func main() {
// 创建执行器
vm := starlet.New()
// 执行简单脚本
result, err := vm.Execute("1 + 2 * 3")
if err != nil {
fmt.Printf("执行错误: %v\n", err)
return
}
fmt.Printf("结果: %v\n", result) // 输出: 7
}
变量传递与获取
func main() {
vm := starlet.New()
// 设置变量到Starlark环境
err := vm.Set("name", "Alice")
if err != nil {
panic(err)
}
// 执行脚本使用变量
result, err := vm.Execute("'Hello, ' + name + '!'")
if err != nil {
panic(err)
}
fmt.Println(result) // 输出: Hello, Alice!
// 从Starlark环境获取变量
value, err := vm.Get("name")
if err != nil {
panic(err)
}
fmt.Printf("变量值: %v\n", value) // 输出: Alice
}
复杂数据类型处理
starlet
自动处理Go与Starlark类型转换:
func main() {
vm := starlet.New()
// 传递结构体数据
data := map[string]interface{}{
"name": "Bob",
"age": 30,
"hobbies": []string{"reading", "coding"},
}
err := vm.Set("user", data)
if err != nil {
panic(err)
}
// 执行脚本处理复杂数据
script := `
user_info = "Name: {}, Age: {}, Hobbies: {}".format(
user["name"],
user["age"],
", ".join(user["hobbies"])
)
`
_, err = vm.Execute(script)
if err != nil {
panic(err)
}
// 获取处理结果
info, err := vm.Get("user_info")
if err != nil {
panic(err)
}
fmt.Println(info) // 输出: Name: Bob, Age: 30, Hobbies: reading, coding
}
使用预置模块
starlet
预加载了多个实用模块:
func main() {
vm := starlet.New()
// 使用time模块
script := `
import time
now = time.now()
formatted = time.format(now, "2006-01-02 15:04:05")
`
_, err := vm.Execute(script)
if err != nil {
panic(err)
}
formatted, err := vm.Get("formatted")
if err != nil {
panic(err)
}
fmt.Printf("当前时间: %v\n", formatted)
// 使用math模块
result, err := vm.Execute("math.sqrt(16)")
if err != nil {
panic(err)
}
fmt.Printf("平方根: %v\n", result) // 输出: 4
}
函数调用
可以在Go中定义函数供Starlark调用:
func main() {
vm := starlet.New()
// 注册Go函数
err := vm.Set("greet", func(name string) string {
return fmt.Sprintf("Hello, %s!", name)
})
if err != nil {
panic(err)
}
// 调用Go函数
result, err := vm.Execute("greet('Charlie')")
if err != nil {
panic(err)
}
fmt.Println(result) // 输出: Hello, Charlie!
}
错误处理
starlet
提供了更友好的错误处理:
func main() {
vm := starlet.New()
// 执行有错误的脚本
_, err := vm.Execute("1 + 'a'")
if err != nil {
if starErr, ok := err.(*starlet.StarletError); ok {
fmt.Printf("Starlark错误: %v\n", starErr.Message)
fmt.Printf("位置: %v\n", starErr.Pos)
} else {
fmt.Printf("其他错误: %v\n", err)
}
}
}
性能考虑
对于需要多次执行的场景,可以预编译脚本:
func main() {
vm := starlet.New()
// 预编译脚本
script := `
def calculate(x):
return x * 2 + 1
`
_, err := vm.Execute(script)
if err != nil {
panic(err)
}
// 多次调用预编译的函数
for i := 0; i < 5; i++ {
result, err := vm.Execute(fmt.Sprintf("calculate(%d)", i))
if err != nil {
panic(err)
}
fmt.Printf("calculate(%d) = %v\n", i, result)
}
}
starlet
通过简化API和自动类型转换,使得在Go中集成Starlark脚本变得更加容易,特别适合需要灵活配置或规则引擎的场景。