self 与冒号方法
本课属于 Coddy Lua 学习旅程的“Luau 入门”单元。第 45 课,共 80 课。
写成 rect.area(rect) 可以运行,但你在 Lua 面向对象编程课中学过一种更好的写法:冒号。rect:area() 调用的效果完全相同:Lua 会自动把冒号前的表作为第一个参数 self 传入。
冒号在定义函数时也很有用。function account:deposit(amount) 会为你声明一个名为 self 的隐藏首个参数:
type Account = {
owner: string,
balance: number,
deposit: (self: Account, amount: number) -> (),
getBalance: (self: Account) -> number,
}
local account = {owner = "Maya", balance = 1500}
function account:deposit(amount: number)
self.balance += amount -- self 是隐式传入的
end
function account:getBalance(): number
return self.balance
end注意,类型定义中会显式声明 self:deposit: (self: Account, amount: number) -> (),即使冒号在实现中隐藏了它。冒号只是一种语法糖,参数仍然存在,类型定义会明确写出它。没有返回值的方法使用空返回类型 -> ()。
调用遵循你已经了解的相同规则:account:deposit(250) 与 account.deposit(account, 250) 完全相同。它的运行时行为和你在面向对象编程章中学到的一样:Luau 只是在此基础上添加了类型。
注意,account 本身没有添加类型注解。Account 类型描述的是完整的表,只有附加了两个方法后,这个表才符合该类型;如果写成 local account: Account = {owner = "Maya", balance = 1500},严格模式会报告缺少方法。
挑战
简单使用冒号语法为账户添加两个方法。
- 在表格下方,定义
function account:deposit(amount: number),将amount加到self.balance上。 - 定义
function account:getBalance(): number,返回self.balance。 - 打印
account:getBalance(),调用account:deposit(120),然后再次打印account:getBalance()。
按“运行代码”:输出先显示 300,然后显示 420。
亲手试试
type Account = {
owner: string,
balance: number,
deposit: (self: Account, amount: number) -> (),
getBalance: (self: Account) -> number,
}
local account = {owner = "Noah", balance = 300}
-- 1)函数 account:deposit(amount: number)
-- 2)函数 account:getBalance(): number
-- 3)输出余额,存入 120,再次输出余额
Luau 入门中的所有课
自己练习: Luau 在线编译器