Lua面向对象编程-我不知道如何实例化一个“类”?
我正在制作一个简单的游戏,一直在跟着 PIL 书籍学习。这里是我游戏的基本情境: http://www.lua.org/pil/16.1.html
我面临一个问题,书中只有一个模块,而我正在尝试让8个模块共同工作。
这里是我游戏的一小部分:我目前只有一个游戏模块、一个游戏板模块和一个输入/输出模块。
我原本以为我明白何时使用冒号和何时使用句点,但我不明白 PIL 中的作者为什么要将“o”传递给“new”方法,以及为什么该方法有一个冒号?
我的游戏模块应该是我最高级别的模块。在其中,我认为我应该使用 board 和输入/输出模块的“new”方法,并让它们共同工作。但是,对于板和输入/输出模块,这些“new”(即初始化)方法看起来像什么样子?
这里是我一直在处理的一些代码(简化版本):
Game = {}
function Game:new(o)
o = {} or o
setmetatable(o, self)
self.__index = self
-- 下面需要 board 和 input_output 实例
o.board = Board:new(o)
o.input_output = Input_Output:new(o)
return o
end
return Game
----------------------------------------------------
Board = {}
function Board:new(o)
o = o or {}
-- 这里需要布局属性
o.layout = { create_layout() }
setmetatable(o, self)
self.__index = self
return o
end
return Board
---------------------------------------------------
Input_Output = {}
function Input_Output:new(o)
o = o or {}
-- 这里需要读写属性
o.read = stdin
o.write = stdout
setmetatable(o, self)
self.__index = self
return o
end
return Input_Output
在类似 Ruby 的面向对象语言中,游戏会持有我板和输入/输出类的实例。然后,如果我钻到 game.board 中,我可以看到 board 的公共属性和公共方法。
然而,当我在游戏中新建这两个“类”时,有些奇怪的事情发生了。我的 self 和 o 变量不是我预期的(我正在使用 lua_inspect)。每个模块实例似乎可能会覆盖 o 变量中的数据?
我很迷茫,我认为这是因为“new”方法。我就是不明白。
有人能解释一下吗? 我主要的问题是 - 示例中的“o”是怎么回事,并且为什么“new”方法有一个冒号?
我正在尝试解释这个问题。这也将帮助我更深入地理解这个问题。
因此,只需查看[http://www.lua.org/pil/16.1.html]中的示例。
`` ` Account = {} function Account:new(o) o = o或{} - 如果用户没有提供,则创建对象 setmetatable(o,self) self.__index = self 返回o end
`` `
##了解Lua中的函数
`` ` function foo(x)返回2 * x end
`` `
只是我们所说的语法糖的一个实例;换句话说,这只是一种漂亮的写法
`` ` foo = function(x)返回2 * x end
`` `
你知道:只是一个。的语法设施。
`` ` function Account:new(o)
`` `
与
`` ` function Account.new(Account,o)
`` `
相同
所以上面,我们知道
`` ` function Account:new(o)
`` `
与
`` ` Account.new = function(Account,o)
`` `
相同
##如何在Lua表中找到某物
`` ` a = Account.new
`` `
以下是查找过程:
`` 查找Account中是否有“新”键? --是--返回Account.new | 否 | 检查“Account”是否具有元表? --否--返回零 | 是 | 检查Account的元表__index字段中是否有“新”键 --否--返回零 | 是 | 假设metaAccount是Account的元表 返回metaAccount.__index.new`
`` `
Account:new作了什么
`` ` o = o或{} - 如果输入的o为nil,则只需创建一个新表
setmetatable(o,self) - 自我是账户,因为“:”,并将o的元表设置为帐户
self.__index = self --与Account.__index = Account相同,这是设置Account的“__index”字段,即o的元表
返回o - 返回o,一个具有元表“Account”的表,而“Account”的“__index”字段也是“Account”
`` `
##它如何工作
我们定义另一个函数
`` ` function Account:print() - 与Account.print = function(self)相同 打印(“类帐户。”) 结束
a = Account:new() - a是一个具有元表“Account”的表,“Account”的“__index”字段也是“Account”
a:print() - 在a的元表Account中查找一个函数作为a的打印,并运行它
-> Class Account.
`` `
你现在应该清楚了...
所以要关注的是“示例中的'o'是什么意思,为什么“new”方法有一个冒号呢?”:
在Lua中,Game是一个类:它是一个带有函数的表。那么什么是Game的一个实例?它是一个表,其元表是其类的表,即Game。
但是在Lua中,表中的函数无法知道它所在的表,除非在调用参数中提供了这个信息。Lua通过在使用冒号而不是点号调用函数时自动将对包含表的引用作为第一个参数传递给函数,使这个过程变得简单。这个第一个参数的名称为“self”。因此,在“new”函数中,使用冒号调用它会提供new所定义的表作为self参数,即Game类。
因此,您可以看到,“o”是您正在创建的实例,并且您使用冒号来调用new,否则您将不得不将它作为参数提供给class表,这样在您的语句中就会出现两次,即冒号提供更好的语法。
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
实际上,Lua 中没有“官方”的类,因此您可以按任何您想要的方式实现它们。在这个特定的实现中,
o是新实例,可能带有一些预定义的参数。它继承了父类的所有成员,包括值或方法(函数) - 在 Lua 中它们都是一样的。如果在此调用中根本不提供o,则会为您创建一个空表。函数定义中的
:只是function Game.new(self, o)的语法糖 - 也就是说,它添加了一个名为self的第一个参数。您应该像这样调用这个函数
local my_game = Game:new()。之后,my_game将成为一个具有my_game.board和my_game.input_output成员的表。您当前的问题并不是非常清晰,不清楚您看到了什么以及它与您的期望有何不同。如果您提供更多细节,我可以添加更多细节来回答。