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
和false
lua
的数字只有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") |