类型断言
本课属于 Coddy Lua 学习旅程的“Luau 入门”单元。第 74 课,共 80 课。
你已经在枚举章中用过一次 ::,把 io.read() 当作 Direction。本课将详细介绍它。
有时,你对某个值的了解比 Luau 的类型检查器更多。例如,你知道一个类型为 any 的值实际上是用户记录。类型断言(也称为类型转换)可以让你告诉检查器:“相信我,把这个值当作这种类型。”Luau 的类型转换运算符是 :::
type User = {id: number, username: string}
local raw: any = {id = 42, username = "alice_dev"}
local user = raw :: User
print(user.username) -- 类型检查器现在知道这些字段了类型转换只会改变类型检查器的判断。它不会在运行时做任何事情。它绝不会转换值:"5" :: any 仍然是字符串 "5",而不是数字 5(要进行真正的转换,请使用 tonumber)。它也绝不会验证值:如果你断言了错误的类型,类型转换本身不会报错。之后,当代码访问不存在的字段时,只会出错。
何时使用:当某个值以 any(或范围较广的联合类型)传入,而且你确实了解它的结构时。何时不要使用:不要用它来消除你不理解的类型错误。这个错误通常是在提醒你有真正的 bug,直接用类型转换消除错误只会掩盖问题。如果可以在运行时验证,优先进行实际检查(例如下一课中的 typeof 守卫)。
挑战
简单读取一条类型为 any 的记录。
- 编写
type User = {id: number, username: string, isActive: boolean}。 - 编写
local function describeUser(data: any): string,使用local user = data :: User进行类型转换,并返回`User {user.id}: {user.username} (Active: {user.isActive})`。 - 打印
describeUser(rawUser2)。
按下 运行代码:输出会显示 User 15: bob_admin (Active: false)。
亲手试试
-- 来自程序外部的原始记录:类型为 any
local rawUser1: any = {id = 7, username = "nina_dev", isActive = true}
local rawUser2: any = {id = 15, username = "bob_admin", isActive = false}
-- 1) type User = {...}
-- 2) describeUser(data: any): string,使用 :: 进行类型转换
-- 3) 打印 describeUser(rawUser2)
Luau 入门中的所有课
自己练习: Luau 在线编译器