Luau 支援使用類型屬性和類型擷取來提供更好的警告、錯誤和建議在 指令編輯器 中。這些類型用於提供更好的警告、錯誤和建議在 指令編輯器 中。
定義類型
使用 type 關鍵字來定義您自己的類型:
type Vector2 = {x: number, y: number}
模式減少
有三種 Luau 類型的預設模式可以在 Script 的第一行設置:
- --!nocheck - 不要檢查類型
- --!nonstrict - 所有腳本的預設模式,只有明確指定類型才會擁有變數類型
- --!strict - 建立所有類型,基於預期或明示的類輸入
類型檢查器的預設模式為 --!nonstrict 。其他兩個模式控制類型檢查器是否嚴格對待類型檢查器在 inferring 和檢查類型對變量和函數的類型進行檢查。任何類型錯誤都會在 指令編輯器 中標示為警告在 指令分析 窗口中顯示。
類型
可以使用 : 操作定義類型標誌,在本地變量後,跟隨類型定義。 預設情況下,在 nonstrict 模式下,所有變量都被指定為類型 any 。
local foo: string = "bar"local x: number = 5
有四種原始類型可以在寫真中使用:
- nil - 沒有值
- boolean - true 或 false
- number - 數字值
- string - 文字
內部 Roblox 中,所有類別、資料類型和數值都有自己的類型,您可以檢查對:
local somePart: Part = Instance.new("Part")local brickColor: BrickColor = somePart.BrickColorlocal material: Enum.Material = somePart.Material
要將類型選項,請在 ? 在標籤的結束:
local foo: string? = nil
這將允許變數是指定的類型 (在此情況下 string 或 nil ) 或 vil 。
字符型
您也可以使用 string 和 boolean 來傳送字串和Boolean值,而不是使用 number1 和 1>number11>:
local alwaysHelloWorld: "Hello world!" = "Hello world!"alwaysHelloWorld = "Just hello!" -- 輸入錯誤:輸入「僅嘿嘿」的錯誤無法轉換為「你好世界」local alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'
類型 Casts
有時候,你可能需要協助類型檢查器,直接將值 Cast 到不同的類型,使用 :: 操作器:
local myNumber = 1local myString: stringmyString = myNumber -- 不 OK;輸入轉換錯誤myString = myNumber :: any -- 好的;所有表達都可以拋出到 "任何"local myFlag = myNumber :: boolean -- Not OK; types are unrelated
功能型輸入
考慮以下功能:
local function add(x, y)
return x + y
end
此功能在 x 添加到 y,但如果其中一個或兩個是字串,則會發生錯誤。Luau 不知道此類型的錯誤,請將類型添加到參數:
local function add(x: number, y: number)
return x + y
end
Luau 現在知道功能需要兩個數字,並且會在你嘗試將任何非數字傳入功能時發出警告:
add(5, 10)add(5, "foo") -- Type error: string could not be converted into number
要定義返回類輸入,請在功能定義的結束放置 : 操作器:
local function add(x: number, y: number): number
要返回多種類型,請將類型放置在括號中:
local function FindSource(script: BaseScript, pattern: string): (string, number)
return 42, true -- 類型錯誤
end
定義功能類型
功能類型可以由使用語法 (in) -> out 定義。使用以前的範例,功能類型是:
type add = (x: number, y: number) -> numbertype FindSource = (script: BaseScript, pattern: string) -> (string, number)
桌子類型
Luau 不具有 table 輸入;相反,桌子類型是使用 {} 語法定義的。一種定義桌子的方法是使用 {type} 語法,這是一種清單輸入。
local numbers: {number} = {1, 2, 3, 4, 5}local characterParts: {Instance} = LocalPlayer.Character:GetChildren()
使用 {[indexType]: valueType} 定義索引類型:
local numberList: {[string]: number} = {Foo = 1,Baz = 10}numberList["bar"] = true -- Type error: boolean can't convert to number
桌子也可以有明確的字串索引在類輸入中定義。
type Car = {
Speed: number,
Drive: (Car) -> ()
}
local function drive(car)
-- 總是遵守速度限制
end
local taxi: Car = {Speed = 30, Drive = drive}
變數
這裡是一個計算任意數量的數量總和的函數:
local function addLotsOfNumbers(...)
local sum = 0
for _, v in {...} do
sum += v
end
return sum
end
如期所欲,此功能可以取得任何值,而 typechecker 不會提出警告,如果您提供一種不可使用的類輸入,例如 string 。
print(addLotsOfNumbers(1, 2, 3, 4, 5)) -- 15print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Attempt to add string to number
相反,將類型할당給 ...,就像你할配任何其他輸入一樣:
local function addLotsOfNumbers(...: number)
現在,第二行會提出類型錯誤。
print(addLotsOfNumbers(1, 2, 3, 4, 5))print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- 類型錯誤:字串無法轉換為數字
但是,此定義類型的定義時不適用:
type addLotsOfNumbers = (...: number) -> number -- Expected type, got ':'
相反,使用語法 ...type 來定義一種變體類輸入。
type addLotsOfNumbers = (...number) -> number
聯絡和交叉
您甚至可以使用 union 或交叉點來定義類型為兩個或更多類型:
type numberOrString = number | stringtype type1 = {foo: string}type type2 = {bar: number}type type1and2 = type1 & type2 -- :{foo: strin字串} & {bar: number}local numString1: numberOrString = true -- 類型錯誤local numString2: type1and2 = {foo = "hello", bar = 1}
定義一個暗示類型
您可以在類型定義中使用 typeof 函數來指定潛在類型:
type Car = typeof({Speed = 0,Wheels = 4}) --> Car: {Speed: number, Wheels: number}
使用 typeof 的一個方法是使用 setmetatable 在 typeof 功能內定義一個 metatable 類型。
type Vector = typeof(setmetatable({}::{x: number,y: number}, {}::{__add: (Vector, Vector|number) -> Vector}))-- Vector + Vector would return a Vector type
一般
generics 是類型的基本級參數。考慮以下 State 物件:
local State = {Key = "TimesClicked",Value = 0}
沒有生成器,此對象的類型將為次
type State = {Key: string,Value: number}
但是,您可能想要 Value 的類型基於來自輸入值,這是類型的來源:
type GenericType<T> = T
<T>1>T 表示可以設置為任何類型的類型。最好的方法是將此視為替換類輸入。 Errors: Error: <T>1>T Severity: major ---
type List<T> = {T}local Names: List<string> = {"Bob", "Dan", "Mary"} -- 類型變成 {字串tring}local Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- Type becomes {number}
generics 也可以在括號內有多個替換。
type Map<K, V> = {[K]: V}
要從以前的 State 對象重新工作,以使用一般類輸入:
type State<T> = {Key: string,Value: T}
功能一覽
函數也可以使用通用。 The State 範例從函數的來自參數中擷取 T 值。
要定義一個通用函數,請在函數名稱中加入 <>:
local function State<T>(key: string, value: T): State<T>
return {
Key = key,
Value = value
}
end
local Activated = State("Activated", false) -- 狀態<button>
local TimesClicked = State("TimesClicked", 0) -- State<number>
輸出類型
要使一種類型可以在 ModuleScript 外使用,請使用 export 關鍵字:
在 ReplicatedStorage 中輸入模型
export type Cat = {Name: string,Meow: (Cat) -> ()}
使用類型模組的脚本
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Types = require(ReplicatedStorage.Types)
local newCat: Types.Cat = {
Name = "metatablecat",
Meow = function(self)
print(`{self.Name} said meow`)
end
}
newCat:Meow()