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ệp | luau main.luau |
| Kiểm tra kiểu mà không chạy | luau-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ác | Cú pháp |
|---|---|
| Number | local age: number = 25 |
| String | local name: string = "Ada" |
| Boolean | local 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 |
| Nil | local n: nil = nil |
| Coroutine / buffer | local co: thread, local b: buffer |
| Tự suy luận, không cần chú thích kiểu | local 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ác | Cú pháp |
|---|---|
| Mảng số | local xs: {number} = {1, 2, 3} |
| Mảng chuỗi | local 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 nhau | local grid: {{number}} = {} |
| Mảng các đối tượng có cấu trúc | local items: {{id: number}} = {} |
| Mảng chỉ đọc | local 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ác | Cú 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ọn | function greet(name: string?) end |
| Giá trị mặc định | function greet(name: string?) name = name or "friend" end |
| Variadic | function sum(...: number): number end |
| Hàm ẩn danh | local f = function(x: number): number return x * 2 end |
| Kiểu hàm | type Adder = (number, number) -> number |
| Tham số callback | function 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ác | Cú pháp |
|---|---|
| Bí danh cho kiểu nguyên thủy | type Health = number |
| Union | type Id = number | string |
| Kiểu tùy chọn là union với nil | type Maybe = string | nil -- same as string? |
| Kiểu literal (singleton) | type Dir = "up" | "down" |
| Intersection | type Both = Named & Aged |
| Bí danh generic | type List<T> = {T} |
| Export từ một module | export type Point = { x: number, y: number } |
| Kiểu của một giá trị có sẵn | type Config = typeof(config) |
| Các khóa của một kiểu table | type 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ác | Cú pháp |
|---|---|
| Cấu trúc viết trực tiếp | local p: { x: number, y: number } = { x = 0, y = 0 } |
| Cấu trúc có tên | type Point = { x: number, y: number } |
| Thuộc tính tùy chọn | type User = { name: string, age: number? } |
| Cấu trúc + indexer | type Bag = { count: number, [string]: any } |
| Mở rộng một cấu trúc | type 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ểu | type Point = { move: (self: Point, dx: number) -> () } |
| Mẫu hàm khởi tạo | function 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ác | Cú pháp |
|---|---|
| Hàm generic | function id<T>(x: T): T return x end |
| Hai tham số kiểu | function pair<A, B>(a: A, b: B): (A, B) end |
| Generic trên một mảng | function first<T>(xs: {T}): T? return xs[1] end |
| Bí danh kiểu generic | type Stack<T> = { items: {T} } |
| Dùng một bí danh với kiểu cụ thể | local s: Stack<string> = { items = {} } |
| Hàm map generic | function 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ác | Cú pháp |
|---|---|
| Type assertion (cast) | local n = value :: number |
| Ép kiểu qua any | local n = (value :: any) :: number |
| Thu hẹp kiểu bằng typeof | if typeof(x) == "string" then -- x is string end |
| Thu hẹp một kiểu tùy chọn | if name then print(#name) end |
| Trả về sớm khi là nil | if not name then return end |
| Thu hẹp một union literal | if dir == "up" then end |
| Kiểm tra lúc chạy và báo lỗi kiểu | assert(typeof(id) == "number", "id must be a number") |
| Khẳng định khác nil rồi mới dùng | local 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ác | Cú pháp |
|---|---|
| Cộng rồi gán | hp += 10 |
| Trừ / nhân / chia rồi gán | hp -= 5, dmg *= 2, dmg /= 2 |
| Chia lấy phần nguyên rồi gán | n //= 2 |
| Chia lấy dư / lũy thừa rồi gán | n %= 3, n ^= 2 |
| Nối chuỗi rồi gán | msg ..= "!" |
| Floor division | local half = 7 // 2 -- 3 |
| Nội suy chuỗi | Hello, {name}! You have {n} items. (đặt trong dấu backtick) |
| Nội suy một biểu thức | Total: {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-else | local label = if hp > 0 then "alive" else "dead" |
| Biểu thức else-if nối tiếp | local t = if n > 0 then "pos" elseif n < 0 then "neg" else "zero" |
| Số nhị phân / số có dấu phân cách | 0b1010, 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ục | Chi tiết |
|---|---|
| Tìm một giá trị trong mảng | table.find(xs, 42) -- index or nil |
| Sao chép nông | local copy = table.clone(t) |
| Đóng băng / kiểm tra đã đóng băng chưa | table.freeze(t), table.isfrozen(t) |
| Cấp phát trước một mảng | table.create(10, 0) |
| Giới hạn khoảng / làm tròn / lấy dấu | math.clamp(x, 0, 1), math.round(x), math.sign(x) |
| Phép toán bit | bit32.band(a, b), bit32.lshift(a, 1) |
| Bị loại bỏ để chạy trong sandbox | io, package, loadstring, loadfile, dofile |
| Lỗi thời nhưng vẫn còn | getfenv, setfenv (chúng tắt các tối ưu hóa) |
| Không có trong Luau | goto / nhãn (Luau dựa trên Lua 5.1) |
| Đọc stdin trên Coddy | io.read() dùng được ở đây, Coddy bổ sung lại hàm này trên nền Luau |
| Đuôi tệp | main.luau (.lua cũng được) |
| Chỉ có trên Roblox, không thuộc Luau gốc | game, 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?
+=, -=, *=, /=, //=, %=, ^=, 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?
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?
--!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?
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?
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?
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.