小工具知识网

当前位置: 首页 > 行业知识 > Lua语法入门和C API基础

行业知识

Lua语法入门和C API基础

2026-11-14 07:33:17 来源:互联网转载

Lua

1. 数据类型

类型解释
nilnil表示无效值,在条件判断中表示false
boolean布尔值
number表示整数或浮点数
string用单引号或双引号引起来的字符串,没有字符只有字符串,[[]]表示原始串
table元组,元素可以是各种类型的数组
function函数
thread协程
userdata用户自定义数据

2. 变量

Lua���弱类型语言,变量无需声明类型即可直接使用,变量的类型可以随赋值的内容随时改变。

()

变量分为全局变量和局部变量。默认是全局变量,全局变量可声明在任意位置,后续任何地方都可使用。局部变量需要加local标识。

3. 运算符

运算符解释
+ - * %和C语法含义一致
/浮点数除法,整数相除可以为浮点数
//整数除法,相除结果为整数
^乘幂,1^10表示1的10次方
> = '北京', '上海', '广州',}cities[4] = '深圳'print(cities[5]) -- nil}for i = 1, 3, 1 do arr[i] = {} for j = 1, 3, 1 do arr[i][j] = i * j endendfor i = 1, 3 do for j = 1, 3 do io.write("arr["..i.."]["..j.."]="..arr[i][j].." ") end print()end name="张三", age="23", dept="开发"}emp["gender"]="男"emp.level=2print("name: ".. emp.name)print("gender:".. emp.gender)print("age: ".. emp.age)print("dept: ".. emp.dept)print("level: ".. emp.level) '北京', name="张三", age="23", '上海', dept="开发", '广州',}print(tb.name, tb.age, tb.dept)print(tb[1], tb[2], tb[3]) { name="zs", age=18 }, { name="ls", age=18 }, { name="ww", age=18 },}for i = 1, 3, 1 do print(emps[i].name..', '.. emps[i].age)endh4接口/h4 h5concat/h5 p仅对table中的数组元素进行连接,可以指定始末下标以及间隔符。/p pre str = table.concat(tb, ', ', 1, 3)/pre h5unpack/h5 p拆包,意思是仅对table中的数组元素进行获取,可以指定始末下标,以多个返回值的形式返回。/p pre i, j, k = table.unpack(tb, 1, 3)/pre h5pack/h5 p打包,意思是将参数列表中的多个参数打包成一个table,并返回。/p pre tb = table.pack(i, j, k)/pre h5insert / remove/h5 pinsert指定下标位置的插入,不指定下标默认尾部插入。remove删除下标位置的数据,默认尾部删除。/p h5sort/h5 p对table的数组内容进行排序,可以指定比较方法。要求所有数组元素类型一致。/p pre table.sort(city)table.sort(city, function(a, b) return a > bend)

迭代器

迭代器ipairs和pairs,分别用于遍历table中的数组元素和所有元素,搭配泛型for使用。

for idx, val in ipairs(tb2) do    print(idx, val)endfor key, val in pairs(tb2) do    print(key, val)end

7. 模块

我们可以将一些变量和函数封装到一个table中,然后将其单独放在一个文件里,这就是一个模块。

外部想要调用该模块内部的东西时,可以require该文件,然后访问该table里的变量和函数。

local rectangle = {}rectangle.pi = 3.14function rectangle.perimeter(a, b)    return (a + b) * 2endrectangle.area = function (a, b)    return a * b;endreturn rectangle
local mod = require("rectanglefile")print(mod.pi)print(mod.perimeter(1, 2))print(mod.area(1, 2))

8. 元表和元方法

为表设置一个元表,修改元表提供的一些元方法,就可以达到对table的操作符进行重载的效果。

setmetatable(t1, meta)setmetatable(t2, meta)
元方法解释
__index定义以.key的形式获取值的行为,tb.key
__newindex定义以.key的行为添加键值对,当表中不存在该key时的行为,tb.key=val
__add定义两个表相加时的行为,tb1+tb2
__sub定义两个表相减时的行为,tb1-tb2
__eq定义两个表判断相等时的行为,tb1==tb2
__tostring定义表转string类型时的行为,tostring(tb)
__call定义以()的方式,类似函数调用table的行为,tb()
meta.__index = function(tb, key)    return rawget(tb, key)endmtb3.__newindex = function (tb, k, v)    rawset(tb, k, v)endprint(emp.name) -- indexemp[key]=val    -- newindex
meta.__add = function(t1, t2)    local res = {}    for i = 1, #t1 do        res[i] = t1[i]    end    for i = 1, #t2 do        res[i + #t1] = t2[i]    end    return resendprint(table.concat(t1 + t2, ', '))
meta.__sub = function(t1, t2)    return {}endprint(table.concat(t1 - t2, ', '))
meta.__eq = function(t1, t2)    if #t1 ~= #t2 then        return false    end    for i = 1, #t1 do        if t1[i] ~= t2[i] then            return false        end    end    return trueendprint(t1 == t2)
meta.__tostring = function(t)    res = ''    for k, v in pairs(t) do        res = res .. k .. ':' .. v .. ', '    end    return resendprint(t)
mtb3.__call = function(t, ...)    for _, v in pairs({...}) do        return t[v]    endreturn t[1]endprint(t())print(t(1))print(t(1, 2))

9. 面向对象

创建对象

Lua中没有类的概念,但是可以使用table中放入属性和函数来模拟类。

如果想让函数获取table本身,可以将.换成:,在函数内部就可以用self访问table内的属性。

local animal = {    name = "animal",    age = 18,    bark = function(self)        print(self.name .. " is bark")    end,}function animal.bark(self)    print(self.name .. " is bark")endfunction animal:bark()    print(self.name .. " is bark")endanimal.bark(animal)animal:bark()

类的定义和继承

只需为table添加一个构造器new函数,在其中绑定一个空表作元表并设置__index为基表。

返回该空表,该空表就是一个新的对象。

如果为该空表添加新的键值对,那么它就是子类。可以为构造器设置一个table类型的参数,将其中属性添加到元表中。

local Person = {    name = nil,    age = nil,}function Person.sleep()    print("sleep now")endfunction Person.work()    print("work now")endfunction Person:new(obj)    local meta = {}    if (type(obj) == "table") then    meta = obj    end    return setmetatable(meta, { __index = self }) -- 在meta表中找不到的键值对,则会到Person表中找endlocal p1 = Person:new()  -- 创建对象local p2 = Person:new({type="wkr"}) -- 创建子类对象print(p1, p2)

10. 协程

Lua中,任意时刻只允许一个协程运行。

接口解释
coroutine.create(func)创建协程并指定回调函数
coroutine.wrap(func)创建协程,调用该函数返回的函数即可启动线程
coroutine.resume(th)启动协程,返回值为协程是否启动成功,以及协程函数的返回值
coroutine.running()返回正在运行的协程对象
coroutine.yield(th)挂起指定协程
coroutine.status(th)查看协程的状态,运行态、挂起态、消亡态

11. 文件

Lua的文件操作,分别以静态函数和实例函数的方式提供,io开头的静态函数和file开头的

接口解释
io.open(name, mode)以指定模式打开指定文件,返回文件对象
io.close(file) / file:close()关闭文件
io.input(file) / io.output(file)将程序标准输入输出重定向到指定的文件
io.read(fmt) / file.read()按格式读取数据,*n读取数字,*a读取全部,*l读取一行,数字读取指定个字符
io.write(str) / file.write()写入数据
file.seek()和C语言类似

12. MySQL

sudo apt install luarocks -ysudo luarocks install luasocket # sudo apt install luarocks -ysudo luarocks install luasql-mysql # sudo apt install lua-sql-mysql
local luasql = require("luasql.mysql")local cli = luasql.mysql()if cli == nil then    print("mysql failed")    os.exit()endlocal conn = cli:connect("cloud", "yyx", "YYXyyx123456", "127.0.0.1", 3306)if conn == nil then    print("conn failed")    os.exit()endlocal res = conn:execute("select * from backup_info;")if res == nil then    print("execute failed")    os.exit()endwhile true do    local row = res:fetch({}, 'a')    if row == nil then        break    end    for k, v in pairs(row) do        io.write(k .. ": " .. v.."  ")    end    print()end

13. Redis

redis-lua

local redis = require('redis')if redis == nil then    print("redis error")    os.exit()endlocal client =redis.connect('127.0.0.1', 6379)if client == nil then    print("conn error")    os.exit()endlocal rsp = client:ping()if not rsp then    print("ping failed")    os.exit()endprint(client.get('key'))

14. C API

Lua通过虚拟栈和C程序交互,想要在C程序中获取Lua的内容都要从栈上取。

接口解释
启动lua
luaL_newstate()创建lua状态机
lua_close()关闭lua
luaL_openlibs(state)打开lua的一些库
执行/加载脚本
luaL_dostring(state, script)执行lua脚本
luaL_loadfile(state, luafilename)加载lua文件编译成函数并压入栈,可通过pcall调用,无参无返回值
get/set全局变量
lua_getglobal(state, varname)将lua中指定的全局变量压入栈
lua_setglobal(state, varname)将栈顶元素设置为全局变量
判断/获取/压入栈
lua_is*(state)判断栈顶的元素是否为某种类型
lua_to*(state, int)获取栈中指定位置的元素,正下标表示从栈底,负下标表示从栈顶
lua_push*(state, type)将指定类型的变量压入栈
lua_pop(state, n)弹出指定个数的栈顶元素
调用/注册函数
lua_pcall(state, argsn, resn, errfunc)调用lua函数,需要先将函数和实参都压入栈,返回值为0表示正常
lua_register(state, const char*, cfunc)将C函数注册到lua中以供其调用
创建C对象
lua_newuserdata(state, size)lua开辟一个c对象并将其压入栈,可由lua获取并使用,内存交给lua管理
get/set表
lua_gettable(state, idx)传入table的栈位置,该函数会先获取栈顶字符串作key,然后将对应val压栈
lua_getfield(state, idx, key)传入table的栈位置,通过key获取val并压栈
lua_setfield(state, idx, key)传入table的栈位置,已知key,获取栈顶元素作val,一并插入table中
lua_settable(state, idx)传入table的栈位置,将栈顶两个元素作键值对,插入table中
元表
luaL_newmetatable(state, name)创建一个指定名称的元表
luaL_getmetatable(state, name)获取指定名称的元表
lua_setmetatable(state, idx)传入table的栈位置,为其绑定元表

上一篇:微信短视频下载方法指南

下一篇:1.18.2怎么开服务器?