语法基础

标识符

字母、下划线、数字组成,不能使用特殊字符 区分大小写
一般约定,以下划线开头连接大写字母,如_VERSION,被保留用于Lua内部全局变量

全局变量

默认情况下,变量是全局的
将变量赋值为nil,删除变量

数据类型

  • nil 空
  • boolean 布尔值
  • number 双精度类型的浮点数
  • string 字符串
  • userdata 任意存储在变量中的C数据结构
  • function 函数
  • thread 独立线程,用于执行协同程序
  • table 表

type(…) 获取数据类型 字符串形式返回

Boolean

false、nil都为假

String

块字符串

  1. string = [[
  2. 这是一块字符串
  3. 可以跨越多行
  4. 不用加引号
  5. ]]
  • print("2"+"3")

print自动将字符串转为数字,输出结果 5
如果要连接字符串输出”23”,需要用”2”..”3”

输出字符串的长度

print(#”kkkkk”)

转义字符

\a 响铃
\b 退格
\f 换页
\n 换行
\r 回车
\t 水平制表
\v 垂直制表
\ 反斜线
\’ 单引号
\” 双引号
\0 空字符
\ddd 八进制数
\xhhh 十六进制数

字符串操作

string.gsub 替换
string.find 查询
string.reverse 反转
string.format 格式化
string.char ASCII码输出字符串
string.byte 字符串转ASCII码
string.len 计算长度
string.rep 重复
string.gmatch 返回迭代字符串,找到下一个迭代的字符串,没找到返回nil
string.gmatch(str, pattern)
string.upper 转大写
string.lower 转小写

Table

表 table 初始索引为1
模块 module
包 package
对象 object

连接表作为字符串

table.concat

插入

table.insert

移除

table.insert

排序

table.sort

Function

函数递归

function factorial(n)
    if n == 0 then
        return 1
    else
        return n * factorial(n - 1)
    end
end

匿名函数

function以匿名函数的方式通过参数传递

function test(tab, fun)
    for k, v in pairs(tab) do
        print(fun(k, v))
    end
end

tab = { key1 = "val1", key2 = "val2" }
test(tab,
        function(key, val)
            -- 匿名函数
            return key .. " = " .. val
        end
)

Thread

线程 协同程序 coroutine
协同程序同一时间只能够运行一个

Userdata

自定义类型

Iterator

迭代器
泛型for迭代器 迭代函数,状态常量,控制变量
无状态的迭代器、多状态的迭代器

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

--[[运行结果
1    1
2    4
3    9
--]]

pairs和ipairs的区别

pairs迭代table,可以遍历表中所有的key,可以返回nil
ipairs迭代数组,不能返回nil,如果遇到nil则退出
ipairs仅遍历值,按照索引升序遍历,索引中断停止遍历

模块和包

模块

module = {}

function module.fun()
    print("module function")
end

return module
require ("module")
local m = require("module")
m.fun()

元表

语雀内容
metatable
改变表的行为,操作两个表
setmetatable(table, metatable)
getmetatable(table)

--普通表
mytable = {}
--元表
mymetatable = {}
--把mymetatable设为mytable的元表
setmetatable(mytable,mymetatable)
--写法2
mytable = setmetatable({},{})
--返回对象元表
getmetatable(mytable) --返回mymetatable

元方法

__index 对表进行访问

--元方法
--[[
通过键访问表,当访问不到这个键,访问元表中的__index
如果是个函数,则直接调用这个函数
如果是个表,访问元表中相应的键
--]]
--index为函数
mytable = setmetatable({ key1 = "val1" },
        { __index = function(metatable, key)

            if key == "key2" then
                return "metatable val"
            else
                return nil
            end
        end })
print(mytable.key1, mytable.key2)
--__index为表
mytable = setmetatable({ key1 = "val1" },
        { __index = { key2 = "metatable val" } })
print(mytable.key1, mytable.key2)

--[[运行结果
val1    metatable val
val1    metatable val
--]]

__newindex 对表进行更新

--__newindex
mymetatable = {}
mytable = setmetatable({ key1 = "val1" }, { __newindex = mymetatable })
print(mytable.key1)

mytable.newkey = "new val2"
print(mytable.newkey, mymetatable.newkey) -- mytable的newkey没有new val2,而mymetatable的newkey变为new val2

mytable.key1 = "new val1"
print(mytable.key1, mymetatable.key1)

mytable = setmetatable({ key1 = "val1" },
        { __newindex = function(mytable, key, value)
            rawset(mytable, key, "\"" .. value .. "\"") -- 绕过元表对原表进行赋值
        end })
mytable.key1 = "new val"
mytable.key2 = 4
print(mytable.key1, mytable.key2)

--[[运行结果
val1
nil    new val2
new val1    nil
new val    "4"
--]]

__add元方法 两表相加

-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用
-- 自定义计算表中最大键值函数 table_maxn,即计算表的元素个数
function table_maxn(t)
    local mn = 0
    for k, v in pairs(t) do
        if mn < k then
            mn = k
        end
    end
    return mn
end

-- 两表相加操作
mytable = setmetatable({ 1, 2, 3 }, {
  __add = function(mytable, newtable)
    for i = 1, table_maxn(newtable) do
      table.insert(mytable, table_maxn(mytable)+1,newtable[i])
    end
    return mytable
  end
})

secondtable = {4,5,6}

mytable = mytable + secondtable
        for k,v in ipairs(mytable) do
print(k,v)
end
模式 描述
__add 对应的运算符 ‘+’.
__sub 对应的运算符 ‘-‘.
__mul 对应的运算符 ‘*’.
__div 对应的运算符 ‘/‘.
__mod 对应的运算符 ‘%’.
__unm 对应的运算符 ‘-‘.
__concat 对应的运算符 ‘..’.
__eq 对应的运算符 ‘==’.
__lt 对应的运算符 ‘<’.
__le 对应的运算符 ‘<=’.

__call 元方法

__call 元方法在 Lua 调用一个值时调用。以下实例演示了计算表中元素的和:

实例

-- 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用
-- 自定义计算表中最大键值函数 table_maxn,即计算表的元素个数
function table_maxn(t)
    local mn = 0
    for k, v in pairs(t) do
        if mn < k then
            mn = k
        end
    end
    return mn
end

-- 定义元方法__call
mytable = setmetatable({10}, {
  __call = function(mytable, newtable)
        sum = 0
        for i = 1, table_maxn(mytable) do
                sum = sum + mytable[i]
        end
    for i = 1, table_maxn(newtable) do
                sum = sum + newtable[i]
        end
        return sum
  end
})
newtable = {10,20,30}
print(mytable(newtable))

以上实例执行输出结果为:
70


__tostring 元方法

__tostring 元方法用于修改表的输出行为。以下实例我们自定义了表的输出内容:

实例

mytable = setmetatable({ 10, 20, 30 }, {
  __tostring = function(mytable)
    sum = 0
    for k, v in pairs(mytable) do
                sum = sum + v
        end
    return "表所有元素的和为 " .. sum
  end
})
print(mytable)

以上实例执行输出结果为:
表所有元素的和为 60

协程

线程:彼此独立运行
一个具有多线程的程序可以同时运行几个线程
协程:彼此协作运行
协同程序需要彼此协作的运行,在任意指定的时刻只有一个协程在运行,被要求挂起的时候挂起

--创建一个协同程序,参数是一个函数,跟resume配合使用
co = coroutine.create(
        function(i)
            print(i)
        end
)
-- 重启
coroutine.resume(co, 1)
-- 状态
print(coroutine.status(co))
-- 创建一个协程,返回一个函数,一旦调用该函数,进入coroutine,和create功能重复
co = coroutine.wrap(
        function(i)
            print(i)
        end
)

co(1)

co2 = coroutine.create(
        function()
            for i = 1, 10 do
                print(i)
                if i == 3 then
                    print(coroutine.status(co2))
                    print(coroutine.running()) -- 正在运行的协程,返回一个线程号
                end
                coroutine.yield() --挂起协程 suspended
            end
        end
)
coroutine.resume(co2)
coroutine.resume(co2)
coroutine.resume(co2)
print(coroutine.status(co2))
print(coroutine.running())

1
dead
1
1
2
3
running
thread: 0000000000620368 false
suspended
thread: 0000000000191588 true
后续详见 ->
语雀内容

三目运算符

a ? b : c lua没有三目运算符
a and b or c 采取这种写法