点号与冒号
本课属于 Coddy Lua 学习旅程的“面向对象编程”单元。第 4 课,共 70 课。
现在你已经了解了点号和冒号语法,下面来看看它们之间的关系,以及没有传入表时会出什么问题。
两个冒号都是简写。定义 function game:addPoints(points) 等同于定义 function game.addPoints(self, points),调用 game:addPoints(10) 等同于调用 game.addPoints(game, 10)。只要表作为第一个参数传入,方法就能正常工作。
没有传入表时,会发生以下情况:
local game = { score = 0 }
function game:addPoints(points)
self.score = self.score + points
end
-- 错误:用点号调用,但没有传入表
game.addPoints(10) -- 错误!self 现在是 10,不是表调用 game.addPoints(10) 时,Lua 不会自动传入 game。值 10 会成为 self,而 self.score 会报错,因为 10 是数字,不是表。
使用点号定义并显式指定 self 的函数可以通过冒号调用,因为冒号会将表作为第一个参数传入:
function game.reset(self)
self.score = 0
end
-- 用冒号调用:game:reset() 等同于 game.reset(game)
game:reset() -- self 正确接收了 game,所以这样能运行这两种定义创建的函数相同,因此如何选择取决于约定:对于使用 self 的函数,使用冒号来定义和调用;对于不使用 self 的函数,使用点号。这样,每次调用都会显示是否传入了表。
挑战
简单创建一个名为 player 的表,其中包含字段 score,并将其初始化为 0。
向该表添加两个函数:
player.setScore(self, value):使用点语法定义,并显式声明self参数。将self.score设置为给定的值。player:addBonus(amount):使用冒号语法定义。将amount加到self.score上。
你会收到两个输入:
- 初始分数值
- 要添加的奖励分数
执行以下步骤:
- 使用点语法调用
setScore(将该表作为第一个参数传入),设置初始分数 - 使用冒号语法调用
addBonus,添加奖励分数 - 打印
player.score的最终值
记住:调用每个函数的方式要与定义该函数的方式一致。
亲手试试
-- 读取输入
local initialScore = tonumber(io.read())
local bonusAmount = tonumber(io.read())
-- TODO:在下方编写你的代码
-- 1. 创建名为 'player' 的表,并将字段 'score' 初始化为 0
-- 2. 使用点号语法添加 player.setScore(self, value),并显式传入 self
-- 3. 使用冒号语法添加 player:addBonus(amount)
-- 4. 使用点号语法调用 setScore(将表作为第一个参数传入)
-- 5. 使用冒号语法调用 addBonus
-- 输出最终分数
print(player.score)这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Lua 在线编译器