2 回答
TA贡献1784条经验 获得超8个赞
我没有用过 go,但看起来你从来没有Book
为你创建的新书设置元表。我相当确定这不会自动发生。
查看我在此处找到的示例https://github.com/stevedonovan/luar/blob/master/luar.go#L52
这里重要的是,当创建用户数据或任何对象(您的书)时,您需要获取全局元表,然后将其设置为元表 L.SetMetaTable(-2)
TA贡献1842条经验 获得超21个赞
在 Lua中编程的C 中的用户定义类型我想出了可行的解决方案。我对 Lua 一无所知,对 Go 知之甚少,所以我的结论可能是错误的。
此版本的Lua 编程是为 Lua 5.0 编写的 - golua使用 Lua 5.1(目前)。
BookCreate 功能
我们创建新的用户数据,而不是推平转到结构到堆栈。然后我们将新创建的元表设置book为“Book”。
L.NewUserdata返回unsafe.Pointer所以我们将它转换为Book.
func BookCreate(L *lua.State) int {
title := L.ToString(1)
book := (*Book)(L.NewUserdata(uintptr(unsafe.Sizeof(Book{}))))
L.LGetMetaTable("Book")
L.SetMetaTable(-2)
book.Id = 1;
book.Title = title;
return 1
}
BookToString 功能
在这里,我们只是把用户数据从堆栈,将其转换为Book。
请注意,我们从堆栈中弹出的内容可能不是指向Bookstruct 的指针,因此如果我们想防止 nil 指针/其他 Go 错误,可能需要进行一些基本的类型检查。
func BookToString(L *lua.State) int {
book := (*Book)(L.ToUserdata(1))
L.PushString(fmt.Sprintf("Book(Id=%d, Title=\"%s\")", book.Id, book.Title))
return 1
}
main 功能
我们初始化新的“Book”元表并使自己成为自己的元表。我们增加了两个方法Create,并__tostring做出“尚书”一个全球性的。
L := lua.NewState()
defer L.Close()
L.OpenLibs()
L.NewMetaTable("Book")
L.PushString("__index")
L.PushValue(-2)
L.SetTable(-3)
L.SetMetaMethod("Create", BookCreate)
L.SetMetaMethod("__tostring", BookToString)
L.SetGlobal("Book")
这就是我们现在可以在 Lua 中做的事情:
local book = Book.Create('Le Petit Prince')
print(book)
print(book:__tostring())
print(Book.__tostring(book))
--out:
Book(Id=1, Title="Le Petit Prince")
Book(Id=1, Title="Le Petit Prince")
Book(Id=1, Title="Le Petit Prince")
我希望有人会觉得它有用。完整代码在这里。
- 2 回答
- 0 关注
- 229 浏览
添加回答
举报