Menu
Coddy logo textTech

Luau 치트시트

타입 검사 모드

파일 첫 줄의 주석이 Luau가 얼마나 엄격하게 검사할지 결정합니다.

모드문법
타입 검사 없음--!nocheck
기본: 주석이 붙은 곳만 검사--!nonstrict
strict: 추론하고 전부 검사--!strict
파일 실행luau main.luau
실행 없이 타입 검사luau-analyze main.luau
lint 경고 하나 끄기--!nolint UnknownGlobal

기본 타입

원시 타입과 변수에 주석을 붙이는 방법.

작업문법
숫자local age: number = 25
문자열local name: string = "Ada"
불리언local ok: boolean = true
옵셔널(nil 가능)local nick: string? = nil
any(검사 제외)local x: any = f()
unknown(더 안전한 any)local x: unknown = f()
never(항상 오류를 던짐)function fail(): never error("boom") end
nillocal n: nil = nil
코루틴 / bufferlocal co: thread, local b: buffer
추론됨 - 주석 불필요local hp = 100 -- number

타입 지정 테이블: 배열과 맵

여전히 Lua 테이블입니다. 타입은 그 안에 무엇이 들었는지 알려줄 뿐입니다.

작업문법
숫자 배열local xs: {number} = {1, 2, 3}
문자열 배열local names: {string} = {}
맵(문자열 키)local ages: {[string]: number} = {}
맵(임의의 키 타입)local seen: {[Player]: boolean} = {}
중첩 배열local grid: {{number}} = {}
형태 배열local items: {{id: number}} = {}
읽기 전용 배열local t = table.freeze({1, 2, 3})
반복(일반화된 반복, Luau 전용)for i, v in xs do print(i, v) end
키와 값 반복for k, v in pairs(ages) do end

함수

매개변수와 반환 타입에 주석을 붙입니다. -> ()는 반환값이 없다는 뜻입니다.

작업문법
타입 지정 매개변수와 반환function add(a: number, b: number): number
반환값 없음function log(msg: string): () end
여러 값 반환function split(s: string): (string, string)
옵셔널 매개변수function greet(name: string?) end
기본값function greet(name: string?) name = name or "friend" end
가변 인자function sum(...: number): number end
익명 함수local f = function(x: number): number return x * 2 end
함수 타입type Adder = (number, number) -> number
콜백 매개변수function each(f: (number) -> ()) end

타입 별칭, 유니온, 리터럴

타입에 한 번 이름을 붙이고 어디서든 재사용하세요.

작업문법
원시 타입 별칭type Health = number
유니온type Id = number | string
옵셔널 = nil과의 유니온type Maybe = string | nil -- same as string?
리터럴(싱글턴) 타입type Dir = "up" | "down"
인터섹션type Both = Named & Aged
제네릭 별칭type List<T> = {T}
모듈에서 내보내기export type Point = { x: number, y: number }
기존 값의 타입type Config = typeof(config)
테이블 타입의 키type K = keyof<Point>

테이블 형태와 메서드

객체를 서술하는 방법과 콜론 호출에 따라오는 self.

작업문법
인라인 형태local p: { x: number, y: number } = { x = 0, y = 0 }
이름 있는 형태type Point = { x: number, y: number }
옵셔널 속성type User = { name: string, age: number? }
형태 + 인덱서type Bag = { count: number, [string]: any }
형태 확장type Admin = User & { level: number }
메서드(콜론 단축 문법)function Point.move(self: Point, dx: number) end
타입 안의 메서드type Point = { move: (self: Point, dx: number) -> () }
생성자 패턴function Point.new(x: number): Point end
고정된 상수(enum 대용)local Color = table.freeze({ Red = 1, Blue = 2 })

제네릭

여러 값 타입에 대해 동작하는 하나의 함수 또는 타입.

작업문법
제네릭 함수function id<T>(x: T): T return x end
타입 매개변수 2개function pair<A, B>(a: A, b: B): (A, B) end
배열에 대한 제네릭function first<T>(xs: {T}): T? return xs[1] end
제네릭 타입 별칭type Stack<T> = { items: {T} }
별칭 인스턴스화local s: Stack<string> = { items = {} }
제네릭 map 함수function map<T, U>(xs: {T}, f: (T) -> U): {U} end
제네릭 팩(가변 인자)function call<T...>(f: () -> T...): T... end

좁히기, 어서션, 타입 가드

이미 알고 있는 값의 타입을 검사기에게 납득시키는 방법.

작업문법
타입 어서션(캐스트)local n = value :: number
any를 거친 캐스트local n = (value :: any) :: number
typeof로 좁히기if typeof(x) == "string" then -- x is string end
옵셔널 좁히기if name then print(#name) end
nil이면 조기 반환if not name then return end
리터럴 유니온 좁히기if dir == "up" then end
런타임 검사assert(typeof(id) == "number", "id must be a number")
nil이 아님을 보장하고 사용local item = assert(find(id), "missing item")

Lua에는 없는 연산자와 문법

일상적인 편의 기능 - Luau 코드가 Lua처럼 보이지 않게 되는 지점입니다.

작업문법
더해서 대입hp += 10
빼기 / 곱하기 / 나누기hp -= 5, dmg *= 2, dmg /= 2
내림 나눗셈 후 대입n //= 2
나머지 / 거듭제곱 후 대입n %= 3, n ^= 2
이어붙여 대입msg ..= "!"
내림 나눗셈local half = 7 // 2 -- 3
문자열 보간Hello, {name}! You have {n} items. (백틱으로 감싸기)
식을 끼워 넣기Total: {price * qty} (백틱으로 감싸기)
루프 계속하기for _, v in xs do if v < 0 then continue end end
if-then-else 표현식local label = if hp > 0 then "alive" else "dead"
else-if를 이은 표현식local t = if n > 0 then "pos" elseif n < 0 then "neg" else "zero"
2진 리터럴 / 자리 구분0b1010, 1_000_000

라이브러리 추가와 Lua와의 차이

Luau가 표준 라이브러리에 더한 함수와, Lua에서 제거한 기능.

항목설명
배열에서 값 찾기table.find(xs, 42) -- 인덱스 또는 nil
얕은 복사local copy = table.clone(t)
불변으로 만들기 / 확인table.freeze(t), table.isfrozen(t)
배열 미리 할당table.create(10, 0)
clamp / round / signmath.clamp(x, 0, 1), math.round(x), math.sign(x)
비트 연산bit32.band(a, b), bit32.lshift(a, 1)
샌드박싱을 위해 제거io, package, loadstring, loadfile, dofile
더 이상 권장되지 않지만 존재getfenv, setfenv (최적화가 비활성화됨)
Luau에 없음goto / 레이블 (Luau는 Lua 5.1 기반)
Coddy에서 stdin 읽기io.read()는 여기서 동작합니다 - Coddy가 Luau 위에 되살려 둡니다
파일 확장자main.luau (.lua도 동작)
Roblox 전용(코어 Luau 아님)game, workspace, Instance.new, task.wait

Luau는 Lua 5.1에 점진적 타입 시스템을 더한 언어로, Roblox가 만들어 오픈소스로 공개했습니다. 이 치트시트는 순수 Lua가 *아닌* 부분을 다룹니다: 타입 주석, 타입 지정 테이블, 유니온과 리터럴 타입, 제네릭, 타입 어서션, 그리고 Luau가 추가한 문법 설탕(+=, 문자열 보간, continue, if-then-else 표현식). 두 언어가 공유하는 테이블, 메타테이블, 코루틴, 문자열 라이브러리는 Lua 치트시트를 함께 열어 두세요.

여기 있는 모든 코드는 표준 Luau이며 luau CLI로 실행하고 luau-analyze로 타입을 검사할 수 있습니다. 필요한 줄을 복사하거나 Luau 플레이그라운드에서 바로 실행해 보세요 - 설치할 것이 없습니다. 타입 시스템을 처음부터 배우고 싶다면 Coddy의 무료 인터랙티브 Luau 강의가 레슨 단위로 쌓아 줍니다.

Luau 치트시트 FAQ

이 Luau 치트시트는 무료인가요?
네. 완전히 무료이며 가입도 필요 없습니다. 유니온, 제네릭, 타입 지정 테이블 문법이 필요할 때 다시 볼 수 있도록 북마크해 두세요.
Luau에 += 연산자가 있나요?
있습니다. 순수 Lua와 달리 Luau는 복합 대입을 지원합니다: +=, -=, *=, /=, //=, %=, ^=, 그리고 문자열 연결용 ..=. 즉 hp += 10은 올바른 Luau(그리고 올바른 Roblox 코드)이며, Lua 5.1에서는 hp = hp + 10으로 써야 합니다. 참고로 Luau에는 ++--가 없습니다.
Lua와 Luau의 차이는 무엇인가요?
Luau는 점진적 타입 시스템을 갖춘 Lua 5.1의 상위 집합입니다. 타입 외에도 백틱 문자열 보간, 복합 대입 연산자, continue, if-then-else 표현식, 내림 나눗셈 //, 일반화된 반복(for i, v in t do), table.find·table.clone·table.freeze 같은 함수를 추가합니다. 샌드박싱을 위해 loadstring, loadfile, dofileio·package 라이브러리를 제거했고, 5.1 기반이라 goto가 없습니다. 일반적인 Lua 코드는 대부분 수정 없이 Luau로 실행됩니다.
Luau에서 타입 검사를 어떻게 켜나요?
파일 첫 줄에 모드 주석을 넣습니다. --!strict는 모든 것을 검사하고 적극적으로 추론하며, --!nonstrict(기본값)는 주석을 붙인 곳만 검사하고, --!nocheck는 검사를 끕니다. 에디터 밖에서는 실행 없이 검사할 때 luau-analyze main.luau, 실행할 때 luau main.luau를 씁니다.
TypeScript처럼 interface를 쓰나요?
아니요. Luau에는 interface 키워드가 없습니다. 객체 형태는 테이블 타입으로 쓰고 type으로 이름을 붙입니다: type User = { name: string, age: number? }. extends 대신 &로 형태를 합치고, 다른 모듈에 공개할 때는 export type을 사용합니다.
이 치트시트가 Roblox 스크립팅과 같은 건가요?
여기 있는 것은 모두 코어 Luau, 즉 언어 자체이므로 Roblox 스크립트와 단독 Luau에 똑같이 적용됩니다. 여기에 *없는* 것은 Roblox 엔진 API(game, workspace, Instance.new, 서비스, 이벤트)로, 언어 위에 올라간 라이브러리이며 Luau가 아니라 Roblox가 문서화합니다.
이 Luau 코드는 어디서 실행할 수 있나요?
Luau 플레이그라운드입니다. 브라우저에서 실제 luau 인터프리터를 stdin 지원과 함께 실행하므로 이 페이지의 어떤 줄이든 붙여 넣고 실행을 누르면 됩니다. 체계적인 연습을 원한다면 인터랙티브 Luau 강의가 같은 내용을 연습 문제, 프로젝트, 수료증과 함께 다룹니다.
Coddy programming languages illustration

Coddy로 Luau 배우기

시작하기