Kiểm tra loại

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

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--!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.BrickColor
local 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 stringboolean :


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 = 1
local myString: string
myString = myNumber -- Không được; loại lỗi chuyển đổi
myString = 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) -> number
type 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)) -- 15
print(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 | string
type type1 = {foo: string}
type type2 = {bar: number}
type type1and2 = type1 & type2 -- {foo: chuỗi} & {bar: number}
local numString1: numberOrString = true -- Lỗi loại
local 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()