Luau hỗ trợ một hệ thống loại tiến bộ thông qua việc sử dụng phân tích loại và suy luận loại.Các loại này được sử dụng để cung cấp cảnh báo, lỗi và đề xuất tốt hơn trong Trình biên tập mã.
Xác định một đánh máy
Sử dụng từ khóa type để định nghĩa các loại riêng của bạn:
type Vector2 = {x: number, y: number}
Các chế độ suy luận
Có ba chế độ suy luận kiểu Luau có thể được đặt trên dòng đầu tiên của một Script :
- --!nocheck — Không kiểm tra loại.
- --!nonstrict — Chỉ xác nhận loại biến nếu chúng được ghi chú rõ ràng.
- --!strict — Tuyên bố tất cả các loại dựa trên đánh máyđược suy luận hoặc được ghi chú rõ ràng.
Các chế độ --!nonstrict và --!strict kiểm soát mức độ nghiêm ngặt mà trình kiểm tra loại là với việc suy luận và kiểm tra các loại cho biến và chức năng.Bất kỳ loại không phù hợp nào trong các tập lệnh được phát hightlight trong Trình soạn thảo tập lệnh và xuất hiện như cảnh báo trong cửa sổ Phân tích tập lệnh.
Loại
Một phân đoạn loại có thể được xác định bằng cách sử dụng operator : sau một biến địa phương, sau đó là một định nghĩa loại.Mặc định, trong chế độ nonstrict , tất cả các biến được gán loại any .
local foo: string = "bar"local x: number = 5
Có bốn loại cơ bản có thể được sử dụng trong một phần đánh dấu:
- nil - không có giá trị
- boolean - true or false
- number - một giá trị số
- string - văn bản
Trong Roblox, tất cả các lớp, kiểu dữ liệu và enums có các loại riêng của chúng mà bạn có thể kiểm tra:
local somePart: Part = Instance.new("Part")local brickColor: BrickColor = somePart.BrickColorlocal material: Enum.Material = somePart.Material
Để làm cho một loại bắt buộc, sử dụng một ? ở cuối phần phân tích:
local foo: string? = nil
Điều này sẽ cho phép biến có thể là loại được chỉ định (trong trường hợp này là string ) hoặc nil .
Loại nguyên tắc
Bạn cũng có thể ném chuỗi và boolean sang các giá trị literal thay vì sử dụng string và boolean :
local alwaysHelloWorld: "Hello world!" = "Hello world!"alwaysHelloWorld = "Just hello!" -- Lỗi loại: Loại "Chỉ xin chào!" không thể được chuyển đổi thành "Xin chào thế giới!"local alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'
Loại phát kiểu
Đôi khi, bạn có thể cần phải hỗ trợ kiểm tra loại bằng cách rõ ràng chuyển một giá trị sang một loại khác với operator :::
local myNumber = 1local myString: stringmyString = myNumber -- Không được; loại lỗi chuyển đổimyString = myNumber :: any -- Được rồi; tất cả các biểu hiệu có thể được ném vào 'bất kỳ'local myFlag = myNumber :: boolean -- Not OK; types are unrelated
Loại chức năng
Xem xét chức năng sau:
local function add(x, y)
return x + y
end
Chức năng này thêm x vào y, nhưng lỗi nếu một hoặc cả hai là một chuỗi.Luau không biết rằng chức năng này chỉ có thể sử dụng số.Để ngăn chặn danh mục vấn đề này, thêm các loại vào các tham số:
local function add(x: number, y: number)
return x + y
end
Luau bây giờ biết rằng chức năng nhận hai số và ném một cảnh báo nếu bạn cố gắng truyền bất kỳ thứ gì không phải là số vào chức năng:
add(5, 10)add(5, "foo") -- Type error: string could not be converted into number
Để xác định một đánh máytrả về, hãy đặt một operator : ở cuối định nghĩa chức năng:
local function add(x: number, y: number): number
Để trả lại nhiều loại, đặt các loại trong dấu ngoặc:
local function FindSource(script: BaseScript, pattern: string): (string, number)
return 42, true -- Lỗi kiểu
end
Xác định một loại chức đánh máy
Một loại chức năng có thể được định nghĩa bằng cách sử dụng syntax (in) -> out. Sử dụng các chức năng từ các ví dụ trước, các loại của các chức năng là:
type add = (x: number, y: number) -> numbertype FindSource = (script: BaseScript, pattern: string) -> (string, number)
Loại bàn
Luau không có loại table ; thay vào đó, các loại bảng được định nghĩa bằng cách sử dụng syntax {}.Một cách để xác định các bảng là sử dụng syntax {type}, định nghĩa một loại danh đánh máy.
local numbers: {number} = {1, 2, 3, 4, 5}local characterParts: {Instance} = LocalPlayer.Character:GetChildren()
Xác định loại chỉ mục bằng cách sử dụng {[indexType]: valueType} :
local numberList: {[string]: number} = {Foo = 1,Baz = 10}numberList["bar"] = true -- Type error: boolean can't convert to number
Các bảng cũng có thể có chỉ mục chuỗi rõ ràng được định nghĩa trong một đánh máy.
type Car = {
Speed: number,
Drive: (Car) -> ()
}
local function drive(car)
-- Luôn luôn đi đến giới hạn tốc độ
end
local taxi: Car = {Speed = 30, Drive = drive}
Biến thể
Đây là một chức năng tính tổng của một số lượng bất kỳ số:
local function addLotsOfNumbers(...)
local sum = 0
for _, v in {...} do
sum += v
end
return sum
end
Như mong đợi, chức năng này có thể nhận bất kỳ giá trị nào, và trình kiểm tra loại sẽ không phát ra cảnh báo nếu bạn cung cấp một đánh máykhông hợp lệ, chẳng hạn như một string.
print(addLotsOfNumbers(1, 2, 3, 4, 5)) -- 15print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Attempt to add string to number
Thay vào đó, gán một loại cho ..., giống như cách bạn gán bất kỳ đánh máynào khác:
local function addLotsOfNumbers(...: number)
Và bây giờ, dòng thứ hai gây ra một lỗi kiểu.
print(addLotsOfNumbers(1, 2, 3, 4, 5))print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Lỗi loại: chuỗi không thể được chuyển đổi thành số
Tuy nhiên, điều này không hoạt động khi viết một định nghĩa loại chức năng:
type addLotsOfNumbers = (...: number) -> number -- Expected type, got ':'
Thay vào đó, sử dụng cú pháp ...type để định nghĩa một đánh máybiến thể.
type addLotsOfNumbers = (...number) -> number
Liên minh và giao lộ
Bạn thậm chí có thể xác định một loại như hai hoặc nhiều loại bằng cách sử dụng một union hoặc intersection:
type numberOrString = number | stringtype type1 = {foo: string}type type2 = {bar: number}type type1and2 = type1 & type2 -- {foo: chuỗi} & {bar: number}local numString1: numberOrString = true -- Lỗi loạilocal numString2: type1and2 = {foo = "hello", bar = 1}
Xác định một loại suy đánh máy
Bạn có thể sử dụng chức năng typeof trong một định nghĩa loại cho các loại được suy luận:
type Car = typeof({Speed = 0,Wheels = 4}) --> Car: {Speed: number, Wheels: number}
Một cách để sử dụng typeof là định nghĩa một loại có thể sử dụng bằng cách sử dụng setmetatable bên trong chức năng typeof:
type Vector = typeof(setmetatable({}::{x: number,y: number}, {}::{__add: (Vector, Vector|number) -> Vector}))-- Vector + Vector would return a Vector type
Thông thường
Các tham số cơ bản của chung cho các loại là ở cấp độ cơ bản. Hãy xem xét đối tượng sau State :
local State = {Key = "TimesClicked",Value = 0}
Không có generics, loại cho đối tượng này sẽ như sau:
type State = {Key: string,Value: number}
Tuy nhiên, bạn có thể muốn loại cho Value được dựa trên giá trị nhận được, nơi mà các biểu tượng xuất hiện:
type GenericType<T> = T
The <T> đại diện cho một loại có thể được đặt thành bất cứ thứ gì. Cách tốt nhất để hiển thị điều này là như một đánh máythay thế.
type List<T> = {T}local Names: List<string> = {"Bob", "Dan", "Mary"} -- Loại trở thành {chuỗi}local Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- Type becomes {number}
Các thông số chung cũng có thể có nhiều thay thế trong dấu ngoặc.
type Map<K, V> = {[K]: V}
Để làm lại đối tượng State từ trước để sử dụng một đánh máychung:
type State<T> = {Key: string,Value: T}
Hàm generics
Chức năng cũng có thể sử dụng các biểu tượng. Ví dụ State đoán giá trị của T từ các tham số nhập vào của chức năng.
Để xác định một chức năng chung, thêm một <> vào tên chức năng:
local function State<T>(key: string, value: T): State<T>
return {
Key = key,
Value = value
}
end
local Activated = State("Activated", false) -- Tình trạng< boolean >
local TimesClicked = State("TimesClicked", 0) -- State<number>
Xuất loại Type
Để làm cho nó có thể được sử dụng bên ngoài một ModuleScript , hãy sử dụng từ khóa export :
Loại module trong ReplicatedStorage
export type Cat = {Name: string,Meow: (Cat) -> ()}
Tập lệnh sử dụng mô-đun Loại
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()