Luau สนับสนุนระบบประเภททีละน้อยผ่านการใช้การอธิบายประเภทและการคาดการณ์ประเภทประเภทเหล่านี้ใช้เพื่อให้คําเตือนที่ดีกว่าข้อผิดพลาดและข้อเสนอแนะใน เครื่องแก้ไขสคริปต์
พิมพ์
ใช้คําหลัก type เพื่อกำหนดประเภทของคุณเอง:
type Vector2 = {x: number, y: number}
โหมดการคาดเดา
มีสามโหมดการคาดเดาประเภท Luau ที่สามารถตั้งค่าได้ในบรรทัดแรกของ Script :
- --!nocheck — อย่าตรวจสอบประเภท
- --!nonstrict — รับประกันประเภทตัวแปรเฉพาะถ้าพวกเขาได้รับการบอกใบ้อย่างชัดเจน
- --!strict — พิมพ์
โหมด --!nonstrict และ --!strict ควบคุมว่าตัวตรวจสอบประเภทจะเคร่งครัดแค่ไหนในการตรวจสอบและตรวจสอบประเภทสำหรับตัวแปรและฟังก์ชันการจับคู่ประเภทใดๆ ที่ไม่ถูกต้องในสคริปต์จะถูกเน้นใน เครื่องมือตัวแก้ไขสคริปต์ และปรากฏเป็นคําเตือนในหน้าต่าง การวิเคราะห์สคริปต์
ประเภท
การแสดงคําอธิบายประเภทสามารถกำหนดได้โดยใช้ตัวประกอบ : หลังจากแปรท้องถิ่นและตามด้วยการกำหนดประเภทโดยค่าเริ่มต้นในโหมด nonstrict ทั้งหมดแปรจะได้รับประเภท any
local foo: string = "bar"local x: number = 5
มีสี่ประเภทพื้นฐานที่สามารถใช้ในการอธิบายได้:
- nil - ไม่มีค่า
- boolean - true or false
- number - ค่าเลขทศนิยม
- string - ข้อความ
ภายใน Roblox ทุกคลาส Classและเอนเนมมีประเภทของตัวเองที่คุณสามารถตรวจสอบได้:
local somePart: Part = Instance.new("Part")local brickColor: BrickColor = somePart.BrickColorlocal material: Enum.Material = somePart.Material
เพื่อทำให้ประเภทเป็นตัวเลือก ให้ใช้ ? ที่ด้านท้ายของการอธิบาย:
local foo: string? = nil
สิ่งนี้จะช่วยให้ตัวแปรเป็นประเภทที่กำหนด (ในกรณีนี้ string ) หรือ nil
ประเภทตัวอักษร
คุณยังสามารถส่งสตริงและบูลีเอนไปเป็นค่าตัวอักษรแทนที่จะใช้ string และ boolean :
local alwaysHelloWorld: "Hello world!" = "Hello world!"alwaysHelloWorld = "Just hello!" -- ข้อผิดพลาดประเภท: ไม่สามารถแปลงข้อความ "สวัสดี!" เป็น "สวัสดีโลก!" ได้local alwaysTrue: true = false -- Type error: Type 'false' could not be converted into 'true'
ประเภทการโค้งคำ
บางครั้งคุณอาจต้องช่วยให้ตัวตรวจสอบสภาพการทำงานโดยการโค้งค่าไปยังประเภทที่แตกต่างโดยใช้ตัวประกอบ :::
local myNumber = 1local myString: stringmyString = myNumber -- ไม่โอเค; ประเภทข้อผิดพลาดการแปลง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
ตามที่คาดไว้ฟังก์ชันนี้สามารถรับค่าใดก็ได้และตัวตรวจสอบประเภทจะไม่เรียกเตือนหากคุณให้ประเภทที่ไม่ถูกต้องเช่น 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
สหภาพและแยกทาง
คุณสามารถกำหนดประเภทเป็นสองประเภทหรือมากกว่าโดยใช้สหภาพหรือการแยก:
type numberOrString = number | stringtype type1 = {foo: string}type type2 = {bar: number}type type1and2 = type1 & type2 -- {foo: สตริง} และ {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 คือการกำหนดประเภท metatable โดยใช้ setmetatable ภายในฟังก์ชัน typeof :
type Vector = typeof(setmetatable({}::{x: number,y: number}, {}::{__add: (Vector, Vector|number) -> Vector}))-- Vector + Vector would return a Vector type
เจเนริกส์
เจเนริกอยู่ในระดับพารามิเตอร์พื้นฐานสำหรับประเภท พิจารณาวัตถุต่อไปนี้ State:
local State = {Key = "TimesClicked",Value = 0}
โดยไม่มีเจเนริก ประเภทสำหรับวัตถุนี้จะเป็นดังนี้:
type State = {Key: string,Value: number}
อย่างไรก็ตาม คุณอาจต้องการให้ประเภทสำหรับ Value ขึ้นอยู่กับมูลค่าที่ได้รับ ซึ่งเป็นที่ที่ generics เข้ามา:
type GenericType<T> = T
เครื่องหมาย <T> หมายถึงประเภทที่สามารถตั้งค่าเป็นอะไรก็ได้ พิมพ์
type List<T> = {T}local Names: List<string> = {"Bob", "Dan", "Mary"} -- ประเภทกลายเป็น {สตริง}local Fibonacci: List<number> = {1, 1, 2, 3, 5, 8, 13} -- Type becomes {number}
เจเนริกส์ยังสามารถมีการแทนที่หลายครั้งภายในเครื่องหมายวงเล็บได้
type Map<K, V> = {[K]: V}
เพื่อปรับแต่งวัตถุ State พิมพ์:
type State<T> = {Key: string,Value: T}
ฟังก์ชัน génériques
ฟังก์ชันยังสามารถใช้ generics ได้ ตัวอย่าง State ให้ค่าของ T จากอาร์กิวเมนต์ที่เข้ามาของฟังก์ชัน
เพื่อกำหนดฟังก์ชันทั่วไป เพิ่ม <> ในชื่อฟังก์ชัน:
local function State<T>(key: string, value: T): State<T>
return {
Key = key,
Value = value
}
end
local Activated = State("Activated", false) -- สถานะ<boolean>
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()