lua使用教程
</div>
<p>闲来无趣,稍微看了一会lua…</p>
运行
1.命令行运行lua命令,在lua的shell中执行语句
1 | zhubenshuli@raspberrypi /var/www/lua_program $ lua |
2.使用lua命令直接执行脚本文件
1 | zhubenshuli@raspberrypi /var/www/lua_program $ lua test.lua |
3.像shell一样运行
1 | zhubenshuli@raspberrypi /var/www/lua_program $ cat hello.lua |
语法
1.注释
1 |
|
2.变量lua的变量没有特殊说明全是全局变量,变量前加local关键字的是局部变量。
可以这样访问全局变量(假设变量名为globalVar):
1 | _G.globalVar |
布尔类型是false的情况只有nil和falselua的数字只有double型,64bits
控制语句
while循环
1 | sum = 0; |
if-else分支
1 | age = 50 |
不等于是~=
字符串的拼接操作符是..
条件语句中的与或非是:and、or、not
for循环
从1加到100
1
2
3
4sum = 0
for i = 1, 100 do
sum = sum + i
end从1到100的奇数和
1
2
3
4sum = 0
for i = 1, 100, 2 do
sum = sum + i
end
until循环
1 | sum = 2 |
函数
递归
1 | function fib(n) |
闭包
1 | function newCounter() |
1 | function myPower(x) |
函数的返回值
函数可以返回多个值
1 | function getUserinfo() |
Table
table是一个KEY VALUE的数据结构:zhubenshuli = {name="xqd", age=25, handsome=false}
遍历table:
1 | for k, v in pairs(zhubenshuli) do |
table的CRUD操作:
1 | zhubenshuli.github = "https://github.com/zhubenshuli" |
也可以这样定义table:t = {[20]=100, ['name']="xqd", [3.14]="PI"}
可以这样访问:t[20]、t["name"]、t[3.14]
数组:arr = {10, 20, 30, 40, 50}
等价于:arr = {[1]=10, [2]=20, [3]=30, [4]=50, [5]=50}
也可以定义成不同类型的数组:arr = {"string", false, 34, function() print("xqd is me!") end}
数组中的函数可以这样调用:arr[4]()
数组中的下标是从1开始的
1 | for i=1, #arr do |
MetaTable和MetaMethod
MetaTable主要用来做一些类似于C++重载操作符式的功能。
比如,有两个分数:
1 | fraction_a = {numeractor=2, denominator=3} |
要实现两个分数的相加:2/3+4/7,就要动用MetaTable:
1 | fraction_op = {} |
为之前定义的两个table设置MetaTable:
1 | setmetatable(fraction_a, fraction_op) |
最后就可以实现两个table相加了:
1 | fraction_c = fraction_a + fraction_b |
__add是MetaMethod,这是lua内建约定的,还有其它如下的MetaMethod:
| MetaMethod | 对应表达式 |
|---|---|
| __add(a,b) | a+b |
| __sub(a,b) | a-b |
| __mul(a,b) | a*b |
| __div(a,b) | a/b |
| __mod(a,b) | a%b |
| __pow(a,b) | a^b |
| __unm(a) | -a |
| __concat(a,b) | a..b |
| __len(a) | #a |
| __eq(a,b) | a==b |
| __lt(a,b) | a < b |
| __le(a,b) | a<=b |
| __index(a,b) | a.b |
| __newindex(a,b,c) | a.b=c |
| __call(a, …) | a(…) |
“面向对象”
__index这个重载,主要是重载了find key的操作。
如果我们有两个对象a和b,想让b作为a的prototype只需要:setmetatable(a, {__index = b})
实例:用一个Window_Prototype的模板加上__index的MetaMethod来创建另一个实例:
1 | Window_Prototype = {x=0, y=0, width=100, height=100} |
于是MyWin就可以访问x、width等等了。
注:当表要索引一个值如table[key],lua会先在table本身中查找key的值,如果没有并且这个table存在一个带_index属性的MethTable,则lua会按照__index所定义的函数逻辑去查找。
1 | Person = {} |
从上面我们可以看到一个new方法和toString方法,其中
1.self就是Person,Person:new(p)相当于Person.new(self,p)
2.new方法的self.__index=self的意图是怕self被扩展后改写,让其保持原样
3.setmetatable这个函数返回的是第一个参数的值
可以这样调用:
1 | me = Person:new() |
继承如下:
1 | Student = Person:new() |
模块
可以直接使用requite("model_name")来载入别的lua文件,文件的后缀名是.lua,载入的时候就直接执行那个文件了。
注意:
1.require函数,载入同样的lua文件时,只有第一次的时候去执行,后面相同的都不执行了。
2.如果要让每一次文件载入都执行的话,可以使用dofile("model_name.lua")函数
3.载入后在需要的时候执行,可以使用loadfile函数。如:
1 | local hello = loadfile("model_name.lua") |
正常用法如下:mymod.lua内容如下:
1 | local xqdModel = {} |
然后就可以这样使用:
1 | local xqd_model = require("mymod") |


