Menu
CoddyTech

Cheat sheet Luau

Các chế độ kiểm tra kiểu

Một chú thích ở dòng đầu tiên của tệp quyết định Luau kiểm tra tệp đó chặt đến mức nào.

Chế độCú pháp
Không kiểm tra kiểu--!nocheck
Mặc định: kiểm tra phần có chú thích kiểu--!nonstrict
Nghiêm ngặt: suy luận và kiểm tra mọi thứ--!strict
Chạy một tệpluau main.luau
Kiểm tra kiểu mà không chạyluau-analyze main.luau
Tắt một cảnh báo lint--!nolint UnknownGlobal

Kiểu cơ bản

Các kiểu nguyên thủy và cách chú thích kiểu cho một biến.

Thao tácCú pháp
Numberlocal age: number = 25
Stringlocal name: string = "Ada"
Booleanlocal ok: boolean = true
Tùy chọn (có thể là nil)local nick: string? = nil
Any (bỏ qua kiểm tra)local x: any = f()
Unknown (any an toàn hơn)local x: unknown = f()
Never (luôn ném lỗi)function fail(): never error("boom") end
Nillocal n: nil = nil
Coroutine / bufferlocal co: thread, local b: buffer
Tự suy luận, không cần chú thích kiểulocal hp = 100 -- number

Table có kiểu: mảng và map

Table vẫn là table của Lua, kiểu chỉ cho biết bên trong chứa gì.

Thao tácCú pháp
Mảng sốlocal xs: {number} = {1, 2, 3}
Mảng chuỗilocal names: {string} = {}
Map (khóa là chuỗi)local ages: {[string]: number} = {}
Map (khóa kiểu bất kỳ)local seen: {[Player]: boolean} = {}
Mảng lồng nhaulocal grid: {{number}} = {}
Mảng các đối tượng có cấu trúclocal items: {{id: number}} = {}
Mảng chỉ đọclocal t = table.freeze({1, 2, 3})
Lặp (dạng tổng quát, chỉ có trong Luau)for i, v in xs do print(i, v) end
Lặp qua khóa và giá trịfor k, v in pairs(ages) do end

Hàm

Chú thích kiểu cho tham số và giá trị trả về; -> () nghĩa là không trả về gì.

Thao tácCú pháp
Tham số có kiểu và kiểu trả vềfunction add(a: number, b: number): number
Không trả về gìfunction log(msg: string): () end
Trả về nhiều giá trịfunction split(s: string): (string, string)
Tham số tùy chọnfunction greet(name: string?) end
Giá trị mặc địnhfunction greet(name: string?) name = name or "friend" end
Variadicfunction sum(...: number): number end
Hàm ẩn danhlocal f = function(x: number): number return x * 2 end
Kiểu hàmtype Adder = (number, number) -> number
Tham số callbackfunction each(f: (number) -> ()) end

Bí danh kiểu, union và literal

Đặt tên cho một kiểu một lần, dùng lại ở mọi nơi.

Thao tácCú pháp
Bí danh cho kiểu nguyên thủytype Health = number
Uniontype Id = number | string
Kiểu tùy chọn là union với niltype Maybe = string | nil -- same as string?
Kiểu literal (singleton)type Dir = "up" | "down"
Intersectiontype Both = Named & Aged
Bí danh generictype List<T> = {T}
Export từ một moduleexport type Point = { x: number, y: number }
Kiểu của một giá trị có sẵntype Config = typeof(config)
Các khóa của một kiểu tabletype K = keyof<Point>

Cấu trúc table và phương thức

Mô tả đối tượng, và self đi kèm khi gọi bằng dấu hai chấm.

Thao tácCú pháp
Cấu trúc viết trực tiếplocal p: { x: number, y: number } = { x = 0, y = 0 }
Cấu trúc có têntype Point = { x: number, y: number }
Thuộc tính tùy chọntype User = { name: string, age: number? }
Cấu trúc + indexertype Bag = { count: number, [string]: any }
Mở rộng một cấu trúctype Admin = User & { level: number }
Phương thức (viết tắt bằng dấu hai chấm)function Point.move(self: Point, dx: number) end
Phương thức trong một kiểutype Point = { move: (self: Point, dx: number) -> () }
Mẫu hàm khởi tạofunction Point.new(x: number): Point end
Hằng số đóng băng (kiểu enum)local Color = table.freeze({ Red = 1, Blue = 2 })

Generic

Một hàm hoặc một kiểu dùng được cho nhiều kiểu giá trị.

Thao tácCú pháp
Hàm genericfunction id<T>(x: T): T return x end
Hai tham số kiểufunction pair<A, B>(a: A, b: B): (A, B) end
Generic trên một mảngfunction first<T>(xs: {T}): T? return xs[1] end
Bí danh kiểu generictype Stack<T> = { items: {T} }
Dùng một bí danh với kiểu cụ thểlocal s: Stack<string> = { items = {} }
Hàm map genericfunction map<T, U>(xs: {T}, f: (T) -> U): {U} end
Generic pack (variadic)function call<T...>(f: () -> T...): T... end

Thu hẹp kiểu, ép kiểu và kiểm tra

Thuyết phục bộ kiểm tra kiểu rằng một giá trị đúng là kiểu bạn biết.

Thao tácCú pháp
Type assertion (cast)local n = value :: number
Ép kiểu qua anylocal n = (value :: any) :: number
Thu hẹp kiểu bằng typeofif typeof(x) == "string" then -- x is string end
Thu hẹp một kiểu tùy chọnif name then print(#name) end
Trả về sớm khi là nilif not name then return end
Thu hẹp một union literalif dir == "up" then end
Kiểm tra lúc chạy và báo lỗi kiểuassert(typeof(id) == "number", "id must be a number")
Khẳng định khác nil rồi mới dùnglocal item = assert(find(id), "missing item")

Toán tử và cú pháp mà Lua không có

Những tiện ích dùng hằng ngày, đây là chỗ code Luau bắt đầu khác hẳn Lua.

Thao tácCú pháp
Cộng rồi gánhp += 10
Trừ / nhân / chia rồi gánhp -= 5, dmg *= 2, dmg /= 2
Chia lấy phần nguyên rồi gánn //= 2
Chia lấy dư / lũy thừa rồi gánn %= 3, n ^= 2
Nối chuỗi rồi gánmsg ..= "!"
Floor divisionlocal half = 7 // 2 -- 3
Nội suy chuỗiHello, {name}! You have {n} items. (đặt trong dấu backtick)
Nội suy một biểu thứcTotal: {price * qty} (đặt trong dấu backtick)
Bỏ qua lần lặp (continue)for _, v in xs do if v < 0 then continue end end
Biểu thức if-then-elselocal label = if hp > 0 then "alive" else "dead"
Biểu thức else-if nối tiếplocal t = if n > 0 then "pos" elseif n < 0 then "neg" else "zero"
Số nhị phân / số có dấu phân cách0b1010, 1_000_000

Thư viện bổ sung và khác biệt với Lua

Các hàm thư viện chuẩn mà Luau thêm vào, và những tính năng Lua mà Luau loại bỏ.

MụcChi tiết
Tìm một giá trị trong mảngtable.find(xs, 42) -- index or nil
Sao chép nônglocal copy = table.clone(t)
Đóng băng / kiểm tra đã đóng băng chưatable.freeze(t), table.isfrozen(t)
Cấp phát trước một mảngtable.create(10, 0)
Giới hạn khoảng / làm tròn / lấy dấumath.clamp(x, 0, 1), math.round(x), math.sign(x)
Phép toán bitbit32.band(a, b), bit32.lshift(a, 1)
Bị loại bỏ để chạy trong sandboxio, package, loadstring, loadfile, dofile
Lỗi thời nhưng vẫn còngetfenv, setfenv (chúng tắt các tối ưu hóa)
Không có trong Luaugoto / nhãn (Luau dựa trên Lua 5.1)
Đọc stdin trên Coddyio.read() dùng được ở đây, Coddy bổ sung lại hàm này trên nền Luau
Đuôi tệpmain.luau (.lua cũng được)
Chỉ có trên Roblox, không thuộc Luau gốcgame, workspace, Instance.new, task.wait

Luau là Lua 5.1 cộng thêm hệ thống kiểu dần dần (gradual typing), ngôn ngữ do Roblox tạo ra và công bố mã nguồn mở. Cheat sheet Luau này tập trung vào những phần *không* có trong Lua thuần: chú thích kiểu, table có kiểu, union và kiểu literal, generic, ép kiểu, cùng các cú pháp tiện lợi mà Luau thêm vào (+=, nội suy chuỗi, continue, biểu thức if-then-else). Với những phần hai ngôn ngữ dùng chung như table, metatable, coroutine, thư viện string, bạn hãy mở cheat sheet Lua bên cạnh trang này.

Mọi đoạn code ở đây đều là Luau chuẩn, chạy được bằng CLI luau và kiểm tra kiểu được bằng luau-analyze. Sao chép phần bạn cần, hoặc thử trực tiếp trong playground Luau, không cần cài đặt gì. Bạn muốn học hệ thống kiểu từ đầu? Khóa học Luau tương tác miễn phí của Coddy xây dựng kiến thức qua từng bài học.

Câu hỏi thường gặp về cheat sheet Luau

Cheat sheet Luau này có miễn phí không?

Có. Cheat sheet Luau này hoàn toàn miễn phí và không cần đăng ký. Lưu trang lại để lần sau tra cú pháp của union, generic hay table có kiểu.

Luau có toán tử += không?
Có. Khác với Lua thuần, Luau hỗ trợ phép gán kết hợp: +=, -=, *=, /=, //=, %=, ^=, và ..= để nối chuỗi. Vì vậy hp += 10 là code Luau hợp lệ (và cũng hợp lệ trong script Roblox), còn trong Lua 5.1 bạn phải viết hp = hp + 10. Lưu ý Luau không có ++ hay --.
Lua và Luau khác nhau thế nào?
Luau là tập mở rộng của Lua 5.1 với hệ thống kiểu dần dần. Ngoài kiểu dữ liệu, Luau còn thêm nội suy chuỗi bằng dấu backtick, các toán tử gán kết hợp, continue, biểu thức if-then-else, phép chia lấy phần nguyên //, vòng lặp tổng quát (for i, v in t do) và các hàm thư viện như table.find, table.clone, table.freeze. Để chạy an toàn trong sandbox, Luau bỏ loadstring, loadfile, dofile cùng hai thư viện io và package, và không có goto vì dựa trên Lua 5.1. Phần lớn code Lua thông thường chạy được trong Luau mà không cần sửa.
Làm sao bật kiểm tra kiểu trong Luau?
Đặt một chú thích chế độ ở dòng đầu tiên của tệp: --!strict kiểm tra mọi thứ và suy luận kiểu triệt để, --!nonstrict (mặc định) chỉ kiểm tra phần bạn đã chú thích kiểu, còn --!nocheck tắt việc kiểm tra. Ngoài trình soạn thảo, chạy luau-analyze main.luau để kiểm tra kiểu mà không thực thi, và luau main.luau để chạy.
Luau có từ khóa interface như TypeScript không?
Không, Luau không có từ khóa interface. Cấu trúc đối tượng được viết dưới dạng kiểu table và đặt tên bằng type: type User = { name: string, age: number? }. Kết hợp các cấu trúc bằng & thay cho extends, và dùng export type để module khác dùng được kiểu đó.
Cheat sheet này có giống lập trình Roblox không?
Mọi thứ ở đây là Luau gốc (ngôn ngữ), nên áp dụng được cho cả script Roblox lẫn Luau chạy độc lập. Phần *không* có ở đây là API của engine Roblox (game, workspace, Instance.new, service, sự kiện): đó là thư viện nằm trên ngôn ngữ và do Roblox viết tài liệu, không phải Luau. Khóa học lập trình game Roblox dạy API đó qua các script chạy trong một game nhỏ kiểu Roblox ngay trên trình duyệt.
Chạy các đoạn code Luau này ở đâu?
Trong playground Luau: nó chạy trình thông dịch luau thật trên trình duyệt, có hỗ trợ stdin, nên bạn có thể dán bất kỳ dòng nào trên trang này rồi nhấn Chạy. Muốn luyện tập có hệ thống, khóa học Luau tương tác đi qua cùng nội dung với bài tập, dự án và giấy chứng nhận.
Hình minh họa các ngôn ngữ lập trình của Coddy

Học Luau cùng Coddy

Bắt đầu