Luau는 형식 주석 및 형식 추론을 사용하여 점진적 형식 시스템을 지원합니다.이러한 유형은 스크립트 편집기에서 더 나은 경고, 오류 및 제안을 제공하는 데 사용됩니다.
입력정의
type 키워드를 사용하여 자체 유형 정의:
type Vector2 = {x: number, y: number}
추론 모드
Script의 첫 줄에 설정할 수 있는 Luau 유형 추론 모드는 세 가지입니다:
- --!nocheck — 형식을 확인하지 마십시오.
- --!nonstrict — 명시적으로 주석이 달린 경우에만 변수 유형을 주장합니다.
- --!strict — 유추된 또는 명시적으로 주석이 달린 입력기반으로 모든 유형을 주장합니다.
--!nonstrict 및 --!strict 모드는 변수와 함수에 대한 유추 및 검사 유형 검사기의 엄격성을 제어합니다.스크립트에서 유형 오차가 발생하면 스크립트 편집기에 표시되어 스크립트 분석 창에 경고로 표시됩니다.
유형
형식 주석은 로컬 변수 뒤에 : 연산자를 사용하여 정의할 수 있으며, 형식 정의가 따릅니다.기본적으로, nonstrict 모드에서는 모든 변수에 any 유형이 할당됩니다.
local foo: string = "bar"local x: number = 5
주석에서 사용할 수 있는 네 가지 기본 유형이 있습니다:
- nil - 값 없음
- boolean - true or 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 일 수 있습니다.
리터럴 유형
문자열과 부울을 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 -- OK; 모든 식이 '任意'에 캐스트될 수 있습니다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
연합과 교차점
연합이나 교집합을 사용하여 유형을 2개 이상의 유형으로 정의할 수도 있습니다:
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}
를 사용하는 한 가지 방법은 함수 내에서 메타테이블 유형을 정의하는 것입니다:
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}
제네릭이 없으면 이 개체의 유형은 다음과 같습니다: Without generics, the type for this object would be as follows:
type State = {Key: string,Value: number}
그러나, Value에 대한 유형이 제네릭이 들어오는 곳인 받은 값을 기반으로 하길 원할 수도 있습니다.
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}
함수 제네릭
함수는 제네릭도 사용할 수 있습니다. 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()