由于想了解一下 OpenResty, 先看看 Lua 的语法。
这是第二篇,接着说 Lua 基础语法。
迭代器
内置的两个迭代器函数,之前都用过了:
pair
ipair
无状态迭代器
function square(iteratorMaxCount, currentNumber)
if currentNumber < iteratorMaxCount
then
currentNumber = currentNumber + 1
return currentNumber, currentNumber * currentNumber
end
end
-- ------------------------------------
for i, n in square, 3, 0
do
print(i, n)
end
-- ------------------------------------
function squares(iteratorMaxCount)
return square, iteratorMaxCount, 0
end
for i,n in squares(3)
do
print(i, n)
end
有状态迭代器
通过闭包 Closure 的方式,实现了迭代器状态的保留。
array = {"Lua", "Tutorial"}
function elementIterator(collection)
local index = 0
local count = #collection
return function ()
index = index + 1
if index <= count
then
-- return the current element of the iterator
return collection[index]
end
end
end
for element in elementIterator(array)
do
print(element)
end
元表 metatable
给原有类型增加或者重载部分方法。
setmetatable(table, metatable)
getmetatable(table)
比如,print
方法会调用变量的 __tostring
方法,重载这个方法可以定义 print
时的输出:
arr = {1, 2, 3, 4}
arr = setmetatable(arr, {__tostring = function (self)
local result = '{'
local sep = ''
for _, i in pairs(self) do
result = result .. sep .. i
sep = ', '
end
result = result .. '}'
return result
end})
print(arr) --> {1, 2, 3, 4}
协程 coroutine
不知道为什么协程类型的关键字是 thread
,这有点让人容易误解。
x = coroutine.create(a_func) -- thread 类型
coroutine.create
coroutine.resume
coroutine.yield
coroutine.runing
coroutine.status
coroutine.wrap
用到的时候再来补充把。
基础操作
时间
采用 os
模块,应该都是系统调用。
os.time([table])
=> 返回 UTC 时间戳,或者指定时间的时间戳。table
包含year
,month
,day
,hour
,min
,sec
,isdst
- 至少包含年月日,时分秒默认是
12:00:00
table
会被当作本地时间
os.date([format[, time]])
还是 C 库中的格式化字符串os.difftime
返回两个时间戳之间的时间差(需要么?)
a = os.date("*t")
for k, v in pairs(a) do
print(string.format("%s = %s", k, tostring(v)))
end
-- hour = 20
-- min = 4
-- wday = 1
-- day = 3
-- month = 7
-- year = 2021
-- sec = 43
-- yday = 185
-- isdst = false
print(os.date('%Y/%m/%d %H:%M:%S'))
-- 2021/07/03 20:06:31
文件 I/O
io
模块
local file = io.open('filepath', 'r')
io.input(file)
io.read() -- 一行
io.close(file)
file = io.input('filepath')
repeat
line = io.read()
if nil == line then
break
end
print(line)
until (false)
io.close(file)
local file = io.open('filepath', 'r')
file:read() -- 一行
file:close()
io.read
可以传以下参数:
*I
默认参数,表示读一行*a
整个文件*n
读一个整数- 整数 表示读指定数量的字符。
file:seek()
io.tmpfile()
io.type(file)
io.flush()
io.lines() -- 可以传文件名作为参数
数学计算
math.pi
math.rad(x) -- 角度转弧度
math.deg(x) -- 弧度转角度
math.sin(x) -- 正弦
math.cos(x) -- 余弦
math.tan(x) -- 正切
math.asin(x) -- 反正弦
math.acos(x)
math.atan(x)
math.max(x, ...)
math.min(x, ...)
math.random([m[, n]]) -- [0, 1) or [1, m) or [m, n)
math.randomseed(x)
math.abs(x)
math.fmod(x, y)
math.pow(x, y)
math.sqrt(x)
math.exp(x) -- e^x
math.log(x)
math.log10(x)
math.floor(x)
math.ceil(x)
math.abs(x)
math.abs(x)
math.abs(x)
math.abs(x)
math.abs(x)
正则表达式
不符合 POSIX 规范!!!因为 regexp 实现相对太大,所以另外做了一套,当然功能就简单很多。
就是 string 的那几个模式匹配方法:
string.find
string.match
string.gmatch
string.sub
string.gsub
用的时候参考 5.4.1 – Patterns