ZGG文档
搜索文档…
在Go程序中嵌入ZGG脚本
ZGG语言从开发之初就支持在Go语言中使用(毕竟ZGG的开发团队所在公司的主力开发语言是Go)。以下是如何在一个Go的项目中集成ZGG引擎

如何集成ZGG?

第一步:安装依赖库

1
go get github.com/zgg-lang/zgg-go
Copied!

第二步:参考下面例子完成代码集成

1.简单使用Demo(展示一下核心接口的用法)

1
package main
2
3
import (
4
"fmt"
5
6
"github.com/zgg-lang/zgg-go"
7
)
8
9
const demoModule = `
10
fib := n => when n {
11
1, 2 -> 1
12
else -> fib(n - 1) + fib(n - 2)
13
}
14
export result := fib(n)
15
`
16
17
const demoExpr = `n ** 2`
18
19
func main() {
20
// 使用源码运行模块
21
if exported, err := zgg.RunCode(demoModule, zgg.Var{"n", zgg.Val{10}}); err != nil {
22
panic(err)
23
} else {
24
fmt.Println("module exported result:", exported["result"].(int64))
25
}
26
// 使用预编译结果运行模块
27
if compiled, err := zgg.CompileCode(demoModule); err != nil {
28
panic(err)
29
} else if exported, err := zgg.RunCode(compiled, zgg.Var{"n", zgg.Val{10}}); err != nil {
30
panic(err)
31
} else {
32
fmt.Println("module exported result:", exported["result"].(int64))
33
}
34
// 使用源码进行表达式求值
35
if result, err := zgg.Eval(demoExpr, zgg.Var{"n", zgg.Val{10}}); err != nil {
36
panic(err)
37
} else {
38
fmt.Println("expr result:", result.(int64))
39
}
40
// 使用预编译结果进行表达式求值
41
if compiled, err := zgg.CompileExpr(demoModule); err != nil {
42
panic(err)
43
} else if result, err := zgg.Eval(compiled, zgg.Var{"n", zgg.Val{10}}); err != nil {
44
panic(err)
45
} else {
46
fmt.Println("expr result:", result.(int64))
47
}
48
}
Copied!

2. 调用Go方法和对象

1
package main
2
3
import (
4
"fmt"
5
6
"github.com/zgg-lang/zgg-go"
7
)
8
9
type User struct {
10
Coins int
11
}
12
13
func (user *User) AddCoins(c int) {
14
user.Coins += c
15
}
16
17
const code = `
18
user.AddCoins(n) // 在ZGG代码里面调用go值的方法
19
`
20
21
func main() {
22
user := User{Coins: 10}
23
_, err := zgg.RunCode(code,
24
zgg.Var{"user", &user}, // 注入Go值,可直接注入
25
zgg.Var{"n", zgg.Val{5}}, // 如果希望注入的值自动转成ZGG基本类型,需要把Go的值用zgg.Val包装一下
26
)
27
if err != nil {
28
fmt.Println("run error:", err)
29
} else {
30
fmt.Println("after RunCode, user.Coins", user.Coins)
31
}
32
}
Copied!

核心接口说明:

func RunCode(script interface{}, opts ...ExecOption) (exported map[string]interface{}, err error)

  • 功能:运行代码模块
  • 参数:
    • script: 待运行的代码,可为源码(string)或者预先编译好的代码对象(ast.Node)
    • opts: 需要注入到运行环境的内容。目前仅支持注入变量
  • 返回值:
    • exported: 运行成功后,返回这个代码模块导出的内容。err为nil时,exported一定不为nil
    • err: 当且仅当运行失败时不为空

func Eval(expr interface{}, opts ...ExecOption) (interface{}, error)

  • 功能: 运行表达式求值
  • 参数:
    • script: 待运行的表达式代码,可为源码(string)或者预先编译好的代码对象(ast.Node)
    • opts: 需要注入到运行环境的内容。目前仅支持注入变量
  • 返回值:
    • exported: 运行成功后,返回这个表达式的返回值
    • err: 当且仅当运行失败时不为空

func CompileCode(code interface{}) (compiled ast.Node, err error)

  • 功能:编译代码模块
  • 参数:
    • code: 待运行的表达式代码,可为源码(string)或者预先编译好的代码对象(ast.Node)
  • 返回值:
    • compiled: 编译结果。如果入参code是预先编译好的,则直接返回code
    • err: 当且仅当运行失败时不为空

func CompileExpr(code interface{}) (ast.Node, error)

  • 功能:编译表达式
  • 参数:
    • code: 待运行的表达式代码,可为源码(string)或者预先编译好的代码对象(ast.Node)
  • 返回值:
    • compiled: 编译结果。如果入参code是预先编译好的,则直接返回code
    • err: 当且仅当运行失败时不为空