## 慣用法(精巧用法)
### 盡可能使用local修飾變量(重要的事情要說三遍!)
原因:
* 使用`local`的變量會在作用域結束時釋放其內存
* 使用`local`的變量會比全局變量的存取更快
* 全局變量會污染全局的命名空間,可能會導致詭異的bug出現
### 直接判斷真假值
~~~
-- 不推薦
if obj ~= nil and willBreak == false then
????-- ...
end
-- 推薦
if obj and not willBreak then
????-- ...
end
~~~
原因:Lua在邏輯判斷時將所有`非false`和`nil`的邏輯判斷視為真,反之視為假,不需要再與布爾值和`nil`進行比對。
但是,在需要對`false`和`nil`進行區分時,需要寫明`==`:`obj == nil`和`obj == false`。
### 默認參數的實現
范式:`param = param or defaultValue`
~~~
function setName(name)
????name = name or 'noName'
????-- ...
end
~~~
原因:`or`會在第一次為`true`的時候斷路,返回其判斷的最后一個值。所以當`name`為空時,`name or 'noName'`返回為`'noName'`,這會將`name`的值自動設置為`noName`。
### 一行代碼實現表的拷貝
~~~
u = {unpack(t)}
~~~
### 一行代碼判斷表是否為空
用`#t == 0`并不能判斷表是否為空,因為`#`預算符會忽略所有不連續的數字下標和非數字下標。
正確做法是:
~~~
if next(t) == nil then
????-- 表為空
????-- ...
end
~~~
因為表的鍵可能為`false`,所以必須與`nil`比較,而不直接使用`~next(t)`來判斷表是否空。
### 更快的插入代碼
~~~
-- 更慢,不推薦
table.insert(t, value)
-- 更快,推薦
t[#t+1] = value
~~~
原因:`[]和#`避免了高層的函數調用開銷。