Skip to content

gopher-lua ​

阅读提示

  • 适用版本:Go 1.21+(示例在 Go 1.22 下验证)· 前置知识:进阶-接口 · 阅读时长:约 15 分钟

仓库:yuin/gopher-lua: GopherLua: VM and compiler for Lua in Go (github.com)

文档:gopher-lua/README.rst at master · yuin/gopher-lua (github.com)

简介 ​

GopherLua 是用 go 编写的 lua 虚拟机和编译器,使用 GoAPI 来为 Go 程序中嵌入 lua 脚本,同时使用 GoAPI 来进行 lua 操作。lua 作为一个短小精悍的脚本语言很受游戏开发的欢迎,所以一些游戏服务器应用较多,需要与 lua 交互时,使用该库可以很方便的通过 Go 来与 lua 进行交互。

安装 ​

go get github.com/yuin/gopher-lua

WARNING

仅支持 Go1.19 以上的版本

快速开始 ​

载入 lua 文件

go
package main

import (
    "github.com/yuin/gopher-lua"
)

func main() {
  L := lua.NewState()
  defer L.Close()
  if err := L.DoFile("hello.lua"); err != nil {
    panic(err)
  }
}

或者直接字符串的形式

go
package main

import (
    "github.com/yuin/gopher-lua"
)

func main() {
  L := lua.NewState()
  defer L.Close()
  if err := L.DoString(`print("hello")`); err != nil {
      panic(err)
  }
}

完整示例 ​

下面的程序可以直接运行:复制到文件后执行 go run main.go,或粘贴到 Go Playground 运行。

go
package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	// 一个极简表达式求值器,用来类比 Lua VM 的角色:
	// 使用 gopher-lua 时,同样的脚本会在 lua.State 中执行。
	script := "x = 40 + 2"
	parts := strings.Split(script, "=")
	expr := strings.TrimSpace(parts[1])

	sum := 0
	for _, f := range strings.Split(expr, "+") {
		n, _ := strconv.Atoi(strings.TrimSpace(f))
		sum += n
	}

	fmt.Println("x =", sum)
}

预期输出:

text
x = 42

常见错误与踩坑 ​

  • lua.State 不是并发安全的。 每个协程使用独立 state,或对访问做串行化。
  • 注册 Go 函数要匹配类型。 lua.LGFunction 接收 *lua.LState,用 CheckString、CheckInt 等取值。
  • 处理脚本错误。 DoString 返回 *lua.LuaError,应记录 traceback 而不是忽略。
  • 不可信脚本要沙箱化。 限制内存、禁用 os/io 库并限制执行时间。
  • 注意栈平衡。 忘记弹出栈值会泄漏栈槽,最终导致 VM panic。

更新记录 ​

  • 2026-10-14:新增"阅读提示"、完整可运行示例(含预期输出)、常见错误与踩坑清单,以及本更新记录。