Lua 輕量級核心只提供基礎語法,**標準庫**才是實戰開發的利器。本文精選四大最高頻庫 (math, table, string, io),提煉 30+ 核心 API,附帶實戰代碼片段、常見坑點、性能提示,作為開發時的「隨身速查表」。
math.sin(x), math.cos(x), math.tan(x)
math.asin(x), math.acos(x), math.atan(x), math.atan2(y, x)
-- 角度↔弧度
math.rad(deg) -- 角度→弧度
math.deg(rad) -- 弧度→角度
print(math.sin(math.rad(30))) -- 0.5
math.floor(x) -- 向下取整 (≤x 最大整數)
math.ceil(x) -- 向上取整 (≥x 最小整數)
math.max(...), math.min(...) -- 多參數極值
-- 偽隨機數 (確定性種子)
math.randomseed(os.time()) -- **啟動時調用一次**
math.random() -- [0,1) 均勻浮點
math.random(n) -- [1,n] 整數
math.random(m, n) -- [m,n] 整數
⚠️ **每次循環調用 `math.randomseed(os.time())` 會導致同秒內生成相同序列!** 僅在程序啟動初始化一次。
math.sqrt(x), math.pow(x, y), math.exp(x), math.log(x) -- 自然對數
math.abs(x), math.fmod(x, y) -- 浮點取模
math.huge, math.pi -- 常量
local t = {10, 20, 30}
table.insert(t, 40) -- 尾部插入 → {10,20,30,40}
table.insert(t, 2, 15) -- 位置 2 插入 → {10,15,20,30,40}
table.remove(t) -- 刪除並返回最後 → 40, t={10,15,20,30}
table.remove(t, 1) -- 刪除並返回位置 1 → 10, t={15,20,30}
**棧/隊列一行實現**:push=table.insert, pop=function(t) return table.remove(t) end。
local t = {20, 10, 2, 3, 4, 89, 20, 33}
table.sort(t) -- 升序
-- 降序
table.sort(t, function(a, b) return a > b end)
-- ❌ 錯誤:table.sort 只能排「數組」(連續整數鍵),不能直接排 map 的 keys
local map = {x=20, z=10, y=30}
table.sort(map) -- 無效!map 無序列部分
-- ✅ 正確:提取 keys 到數組,排序數組,再遍歷
local keys = {}
for k in pairs(map) do keys[#keys+1] = k end
table.sort(keys)
for _, k in ipairs(keys) do print(k, map[k]) end
local t = {"Jelly", "Think", "Is", "Good"}
local s = table.concat(t, " ") -- "Jelly Think Is Good"
-- 可選參數:table.concat(t, sep, start, end)
string.len(s) / #s -- 長度
string.rep(s, n) -- 重複 n 次
string.lower(s), string.upper(s) -- 大小寫轉換
string.sub(s, i, j) -- 子串 [i, j],**1-based,負索引從尾部倒數**
-- 示例
string.sub("[Jelly Think]", 2, -2) -- "Jelly Think" (去首尾括號)
string.sub("abcdef", 2, 4) -- "bcd"
string.char(97, 98, 99) -- "abc" (ASCII 碼→字符)
string.byte("abc", 1, 2) -- 97, 98 (字符→ASCII 碼,可指定范圍)
string.byte("abc", -1) -- 99 (最後一個)
string.format("%.2f%%", 99.987) -- "99.99%"
string.format("%04d-%02d-%02d", 2024, 1, 15) -- "2024-01-15"
-- 格式符同 C printf:%d %f %s %x %q (Lua 轉義字符串) 等
string.find(s, pattern [, init [, plain]]) -- 返回起止位置
string.match(s, pattern [, init]) -- 返回捕獲組
string.gmatch(s, pattern) -- 返回迭代器函數
string.gsub(s, pattern, repl [, n]) -- 替換,返回新串+替換次數
-- 模式字符:. %a %d %w %s (字母/數字/字母數字/空白)
-- 魔法字符:() . % + - * ? [ ] ^ $ 需 % 轉義
-- 捕獲:() 內容可在 repl 中用 %1 %2 引用
io.input("data.txt") -- 設置當前輸入文件
io.output("out.txt") -- 設置當前輸出文件
local line = io.read() -- 讀一行 (默認 "*l")
io.write("Hello") -- 寫入當前輸出
io.close() -- 關閉當前文件
local f = assert(io.open("data.txt", "r")) -- 打開只讀
for line in f:lines() do print(line) end -- 迭代器逐行讀
f:close()
local f = assert(io.open("out.txt", "w"))
f:write("Hello\n")
f:flush() -- 強制刷新緩衝區
f:close()
| 模式 | 含義 |
|---|---|
"*n" | 讀數字 |
"*a" | 讀整個文件 |
"*l" | 讀一行 (默認,去換行符) |
"*L" | 讀一行 (保留換行符) |
n | 讀 n 字節 |
io.stdin, io.stdout, io.stderr -- 預定義文件句柄
io.read() -- 等價 io.stdin:read()
io.write("log") -- 等價 io.stdout:write("log")
| 誤區 | 正確做法 |
|---|---|
| `math.random` 不設種子 | 啟動時 `math.randomseed(os.time())` 一次 |
| `table.sort` 直接排 map | 提取 keys 到數組排序 |
| 字符串下標以 0 開始 | **Lua 字符串/數組下標從 1 開始**,負數從尾部 -1 |
| `string.gsub` 修改原串 | **返回新串**,需 `s = string.gsub(s, ...)` |
| 文件未關閉導致數據丟失 | 用 `assert(io.open(...))` + 顯式 `:close()` 或 ` |