这篇文章源于我看到某乎某用户觉得lua语法“违反直觉”,我觉得有这感觉源于lua的语法糖,如果流于表面的把这些加糖后的语法往C,C#,java等语义上套确实容易产生误解。另外xLua群上也经常会问些因为对语法理解问题导致问题。
lua里头一些很常见的语法,其实都是加了糖。比如这个:
local a = {}
a.f = 10
去糖后其实是这样的,
local a = {}
a["f"] = 10
去糖后更清晰了,a是table,table本质上就是一个hashmap,我们往一个hashmap里头设置了键值对。
再看这个:
local calc = {}
function calc.add(a, b) --语法糖
end
第一次去糖后是这样:
local calc = {}
calc.add = function(a, b)
end
再按照文章开篇第一个语法糖再去一次糖,就变成了
local calc = {}
calc["add"] = function(a, b)
end
所以,仍然是对一个hashmap设置键值对,只不过值相对于c/c#/java比较特殊,这是个function(准确来说是一个closure),因为lua里头函数是first-class的,可以作为一个普通值来处理。
再来
function add(a, b)
return a + b
end
一次脱糖
add = function(a, b)
return a + b
end
二次脱糖就比较复杂,分两种情况:前面有local变量add,前面没有。
前面有local add,其实就是对add变量的一次赋值,如果没有,还要脱糖:
_ENV["add"] = function(a, b) #>=lua53
return a + b
end
其实就是对一个特殊的table设置键值对。
跟着来一个导致很多人踩坑的冒号语法糖:
calc:add(1, 2) --语法糖
脱糖后是这样的
calc.add(calc, 1, 2)
和冒号语法糖相关的语法糖
function calc:add(a, b) --语法糖
end
一次脱糖后是这样
calc.add = function(self, a, b)
end
注意,你按脱糖后的写法,那个self你写啥名字都可以。