## 惯用法(精巧用法)
### 尽可能使用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
~~~
原因:`[]和#`避免了高层的函数调用开销。