lua基本语法
阅读时间:全文 1001 字,预估用时 6 分钟
创作日期:2022-04-12
上篇文章:lua的string内置库
下篇文章:RN脚手架打包乱码问题定位修复
BEGIN
lua是非常流行的胶水语言,由于它语法简单易于学习,常用来编写游戏脚本、算法程序、配置程序,如配合nginx使用、配置neovim等,这里学习lua主要是用来配置neovim。
0. 注释
- 单行注释:
-- 单行注释
- 多行注释:
--[[
多行注释
--]]
1. 变量定义
- 数值:
num = 42
- 字符串:
- 当行文本:
'
、"
- 多行文本:
[[]]
,使用引号有些字符需要转译,这种就不需要
- 当行文本:
- nil表示空,如:js的null、py的None
1.1. 操作
- 数值自增与赋增:
++
、--
、+=
、-=
- 仅nil和false在条件判断时为false,0或空字符等都是true
~=
表示不等于- 未定义变量返回nil,以避免报错
- 变量不使用local定义,则变量会被挂到
_G
上,_G
是lua的全部变量名 - 字符串使用
..
拼接, 如:print('aa' .. 'bb')
2. 流程控制
- while语句:
while 条件 do 执行语句 end
- if语句:
if 条件 then 执行语句 elseif 条件 else 执行语句 end
- 三元表达式:
条件 and 值 or 值
- for语句:
for j = 数值, 极限值[, 步进值] do 执行语句 end
,其中步进值默认为加1 - repeat语句:
repeat 执行语句 until 条件
3. function函数
function f() 执行语句 end
等价于f = function () 执行语句 end
local function f() 执行语句 end
等价于local f; f = function () 执行语句 end
- 在命令行中第一个单词为等于号
=
则解释器会将=
转译为return
,但是在函数中使用=
返回值会报错
4. table表(元组、对象)
lua中的table功能包含了元组和对象,和js的对象比较像
如定义:v = {1, 2, 3, [0] = 'a', ['b'] = 'b', 4}
, lua会将不是等号赋值的取出来值当数组用,等号赋值的取出来当对象用,如该赋值会生成两个v: v = {1, 2, 3, 4}
和v = {[0] = 'a', ['b'] = 'b'}
,取值方式示例:
> v = {1, 2, 3, [0] = 'a', ['b'] = 'b', 4}
> v[0]
a
> v[1]
1
> v['b']
b
> v[4]
4
> #v
4
> for key, val in pairs(v) do print(key, val) end
1 1
2 2
3 3
4 4
0 a
b b
#v
表示数组长度(非等于号赋值)pairs(v)
会生成table的键值迭代器
4.1. table的内置函数
-- __add(a, b) for a + b
-- __sub(a, b) for a - b
-- __mul(a, b) for a * b
-- __div(a, b) for a / b
-- __mod(a, b) for a % b
-- __pow(a, b) for a ^ b
-- __unm(a) for -a
-- __concat(a, b) for a .. b
-- __len(a) for #a
-- __eq(a, b) for a == b
-- __lt(a, b) for a < b
-- __le(a, b) for a <= b
-- __index(a, b) <fn or a table> for a.b
-- __newindex(a, b, c) for a.b = c
-- __call(a, ...) for a(...)
使用setmetatable方法修改内置函数:setmetatable(v, {__add = function, __index = otherTable}
示例:
-- 重构加法
f1 = {a = 1, b = 2}
f2 = {a = 2, b = 3}
metafraction = {}
function metafraction.__add(f1, f2)
sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
end
setmetatable(f1, metafraction)
setmetatable(f2, metafraction)
--[[
-- 等价于
metatable = {__add = function (f1, f2) return {a = f1.b * f2.b, b = f1.a * f2.b + f2.a * f1.b} end}
setmetatable(f1, metatable)
setmetatable(f2, metatable)
--]]
s = f1 + f2
-- 属性继承
defaultFavs = {animal = 'gru', food = 'donuts'}
myFavs = {food = 'pizza'}
setmetatable(myFavs, {__index = defaultFavs})
eatenBy = myFavs.animal
5. class类
lua中的类是基于table加function实现的
-- 定义类
Dog = {}
-- 定义类的构造函数
function Dog:new()
newObj = {sound = 'woof'}
self.__index = self
return setmetatable(newObj, self)
end
-- 给类增加方法
function Dog:makeSound()
print('I say ' .. self.sound)
end
-- 实例化
mrDog = Dog:new()
-- 调用类的makeSound方法
mrDog:makeSound() -- 输出:'I say woof'
-- 新建并继承类
LoudDog = Dog:new()
-- 重构makeSound类方法
function LoudDog:makeSound()
s = self.sound .. ' '
print(s .. s .. s)
end
-- 实例化
seymour = LoudDog:new()
-- 调用类的makeSound方法
seymour:makeSound() -- 输出:'woof woof woof'
6. modules模块
- 使用require方法引入模块,相同引入模块则第二次是第一次的引用
- 使用dofile类似于require,不过相同引入模块是没有引用关系
- 使用loadfile方法执行模块文件
- 使用load执行文本代码
FINISH
上篇文章:lua的string内置库
下篇文章:RN脚手架打包乱码问题定位修复