Kiểm tra kiểu

*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 kiểm tra từ từ thông qua sử dụng các hàm kiểm tra kiểu và kiểu suy luận. Các hệ thống 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 Script .

Định nghĩa một kiểu

Sử dụng từ khóa type để xác định các loại của riêng bạn:


type Vector2 = {x: number, y: number}

Các chế độ suy luận

Có ba chế độ dự đoán Luau có thể được cài đặt trên dòng đầu tiên của một Script :

  • --!nocheck - Đừng kiểm tra các loại
  • --!nonstrict - Chế độ mặc định cho tất cả các script, chỉ xác định các loại biến nếu chúng được xác định rõ ràng
  • --!strict - Phản ánh tất cả các loại dựa trên đánh máydựa đoán hoặc rõ ràng đã được ghi nhận

Chế độ mặc định cho kiểm tra kiểu là --!nonstrict . Hai chế độ khác điều khiển cách kiểm tra kiểu kiểm tra kiểu kiểm tra kiểu kiểm tra kiểu kiểm tra kiểu kiểm tra kiểm tra kiểm tra kiểm tra kiểm tra kiểm tra kiểm tra kiểm tra kiểm tra kiểm tra kiểm tra kiểm tra kiể

Các loại

Một hành động an toàn 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 kiểu. Bởi mặc định, trong chế độ nonstrict``any, tất cả các biến đều được giao hành động 2>2> .


local foo: string = "bar"
local x: number = 5

Có bốn loại thô sơ có thể được sử dụng trong một bản ghi:

  • nil - không có giá trị
  • boolean - true hoặc false
  • number - một giá trị số
  • string - văn bản

Trong Roblox, tất cả các lớp, loại dữ liệu và enums đều có các loại riêng của chúng mà bạn có thể kiểm tra chống lại:


local somePart: Part = Instance.new("Part")
local brickColor: BrickColor = somePart.BrickColor
local material: Enum.Material = somePart.Material

Để làm cho một kiểu bắt buộc, hãy sử dụng một ? ở cuối cùng của phần thông báo:


local foo: string? = nil

Điều này sẽ cho phép biến đổi là một trong những loại được xác định (trong trường hợp này string hoặc nil .

Các kiểu chữ

Bạn cũng có thể dùng dấu chấu câu và dấu chấu câu để thay thế giá trị trong stringboolean :


local alwaysHelloWorld: "Hello world!" = "Hello world!"
alwaysHelloWorld = "Just hello!" -- Lỗi nhập: Bạn không thể chuyển đổi "Chào đơn giản!" thành "Xin chào thế giới!"
local alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'

Loại Cast

Đôi khi, bạn có thể cần phải hỗ trợ kiểm tra hệ thống bằng cách rõ ràng gắn một giá trị với một kiểu khác với :: Operator:


local myNumber = 1
local myString: string
myString = myNumber -- Không được; nhập một lỗi chuyển đổi
myString = myNumber :: any -- OK; tất cả các biểu tượng đều có thể được thả vào 'bất kỳ'
local myFlag = myNumber :: boolean -- Not OK; types are unrelated

Hệ

Xem xét chức năng sau đây:


local function add(x, y)
return x + y
end

Hàm này thêm x vào y, nhưng lỗi nếu một hoặc cả hai trong số họ là một chuỗi. Luau không biết rằng hàm này chỉ có thể sử dụng số. Để ngăn chặn thể loại này của vấn đề, hãy thêm các loại vào các biến:


local function add(x: number, y: number)
return x + y
end

Luau bây giờ biết rằng hàm này lấy hai số và ném một cảnh báo nếu bạn cố gắng truyền bất kỳ điều gì không phải là một số vào hàm:


add(5, 10)
add(5, "foo") -- Type error: string could not be converted into number

Để định nghĩa một hệ đánh máytrả về, hãy đặt một biểu tích : ở 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 những dấu chấu hỏi:


local function FindSource(script: BaseScript, pattern: string): (string, number)
return 42, true -- Các loại lỗi
end

Định nghĩa một kiểu hành động

Một loại chức năng có thể được định nghĩa bằng cách sử dụng cấu trúc (in) -> out . Sử dụng các hàm từ các ví dụ trước, các loại hàm là:


type add = (x: number, y: number) -> number
type FindSource = (script: BaseScript, pattern: string) -> (string, number)

Các loại bảng

Luau không có kiểu table nhưng thay vào đó, kiểu bảng được định nghĩa bằng cách sử dụng {} ngữ cảnh. Cách đơn giản nhất để định nghĩa bảng là sử dụng kiểu {type} , which defined một kiểu danh sách.


local numbers: {number} = {1, 2, 3, 4, 5}
local characterParts: {Instance} = LocalPlayer.Character:GetChildren()

Định nghĩa các 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ó cá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 theo giới hạn tốc độ
end
local taxi: Car = {Speed = 30, Drive = drive}

Biến

Đây là một hàm tính toán tổng số một bộ số bất kỳ:


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ể lấy bất kỳ giá trị nào, và hộp kiểm tra kiểu sẽ không nâng cấp 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 đó, hãy 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 nảy ra một lỗi kiểu.


print(addLotsOfNumbers(1, 2, 3, 4, 5))
print(addLotsOfNumbers(1, 2, "car", 4, 5)) -- Lỗi nhập: chuỗi không thể được chuyển thành số

Tuy nhiên, điều này không hoạt động khi viết một định nghĩa hệ thống chức năng:


type addLotsOfNumbers = (...: number) -> number -- Expected type, got ':'

Thay vào đó, sử dụng cấu trúc ...type để định nghĩa một đánh máyđa biến.


type addLotsOfNumbers = (...number) -> number

Liên kết và giao thoa

Bạn thậm chí có thể định nghĩa một loại như hai hoặc nhiều loại bằng cách sử dụng một liên kết hoặc giao điểm:


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 -- Loại lỗi
local numString2: type1and2 = {foo = "hello", bar = 1}

Định nghĩa một kiểu dữ liệu

Bạn có thể sử dụng chức năng typeof trong một định nghĩa kiểu để xác định các kiểu dữ liệu tương tự:


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 metatable bằng cách sử dụng setmetatable 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

Generics are at a basic level parameters for types. Hãy xem đối tượng State dưới đây:


local State = {
Key = "TimesClicked",
Value = 0
}

Mà không có genéric, loại cho đối tượng này sẽ là như sau:


type State = {
Key: string,
Value: number
}

Tuy nhiên, bạn có thể muốn kiểu cho Value để có cơ sở trên giá trị đang đến, nơi các genéric đến:


type GenericType<T> = T

The <T> đề cập đến một loại có thể được đặt bất cứ thứ gì. Cách tốt nhất để xem này là như một đánh máythay thế.


type List<T> = {T}
local Names: List<string> = {"Bob", "Dan", "Mary"} -- Type trở thành {chuỗi}
local Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- Type becomes {number}

Generics cũng có thể có nhiều thay thế trong các khoảng trống.


type Map<K, V> = {[K]: V}

Để chỉnh sửa lại đối tượng State từ trước đó để sử dụng một đánh máygenéric:


type State<T> = {
Key: string,
Value: T
}

Hàm Generics

Hàm cũng có thể sử dụng thuốc nào. Ví dụ State infers giá trị của T từ các đại diện đầu vào của hàm.

Để định nghĩa một chức năng genéric, hãy 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) -- Tiểu luật<button>
local TimesClicked = State("TimesClicked", 0) -- State<number>

Xuất

Để làm cho nó có thể được sử dụng ngoài của một ModuleScript , hãy sử dụng từ khóa export :

Các hạng module trong ReplicatedStorage

export type Cat = {
Name: string,
Meow: (Cat) -> ()
}
Script sử dụng Modul 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()