如何在gopher-lua中传递Go结构体并在lua脚本中访问其字段
解决方案
gopher-lua 中传递 Go 结构体给 Lua 脚本、实现 Lua 侧访问结构体字段,核心是通过 lua.LUserData 类型配合结构体专属元表注册实现,可按以下步骤操作:
步骤1:定义需要传递的Go结构体
首先声明你要透传的结构体,注意需要访问的字段首字母必须大写(Go 可见性要求):
type CustomData struct { Id int Title string Price float64 }
步骤2:注册结构体元表,实现字段访问逻辑
提前给目标结构体注册专属元表,通过 __index 元方法处理 Lua 侧的字段访问请求:
func registerCustomDataType(L *lua.LState) { // 创建结构体专属元表 mt := L.NewTypeMetatable("CustomData") L.SetGlobal("CustomData", mt) // 实现__index元方法,映射结构体字段 L.SetField(mt, "__index", L.NewFunction(func(L *lua.LState) int { // 取出UserData里的结构体实例 data := L.CheckUserData(1).Value.(*CustomData) // 取出Lua侧要访问的字段名 field := L.CheckString(2) switch field { case "Id": L.Push(lua.LNumber(data.Id)) case "Title": L.Push(lua.LString(data.Title)) case "Price": L.Push(lua.LNumber(data.Price)) default: L.Push(lua.LNil) } return 1 })) }
如果需要支持 Lua 侧修改结构体字段,可给元表额外添加 __newindex 元方法实现赋值逻辑。
步骤3:将结构体实例包装为UserData传递给Lua
调用 Lua 函数前,把结构体指针包装为 lua.LUserData 并绑定注册好的元表,即可作为普通参数传递:
func main() { L := lua.NewState() defer L.Close() // 先注册结构体类型 registerCustomDataType(L) // 加载你的Lua脚本 if err := L.DoFile("your_script.lua"); err != nil { panic(err) } // 创建Go结构体实例 myData := &CustomData{ Id: 1001, Title: "测试商品", Price: 29.9, } // 包装为UserData并绑定元表 ud := L.NewUserData() ud.Value = myData L.SetMetatable(ud, L.GetTypeMetatable("CustomData")) // 调用Lua函数时直接作为参数传入即可 err := L.CallByParam(lua.P{ Fn: L.GetGlobal("processData"), // Lua侧目标函数名 NRet: 0, Protect: true, }, ud) if err != nil { panic(err) } }
步骤4:Lua侧直接访问字段
Lua 脚本中可以直接用 . 语法访问你暴露的结构体字段:
function processData(data) print("数据ID:"..data.Id) print("数据标题:"..data.Title) print("数据价格:"..data.Price) end
内容的提问来源于stack exchange,提问作者sam-tech
相关产品推荐
相关产品推荐

