lua使用教程

闲来无趣,稍微看了一会lua…

运行

1.命令行运行lua命令,在luashell中执行语句

1  
2  
3  
4  
5  
zhubenshuli@raspberrypi /var/www/lua_program $ lua  
Lua 5.3.1  Copyright (C) 1994-2015 Lua.org, PUC-Rio  
> ("hello world!")  
hello world!  
>  

—|—

2.使用lua命令直接执行脚本文档

1  
2  
zhubenshuli@raspberrypi /var/www/lua_program $ lua test.lua  
hello world!  

—|—

3.像shell一样运行

1  
2  
3  
4  
5  
6  
zhubenshuli@raspberrypi /var/www/lua_program $ cat hello.lua  
#!/usr/local/bin/lua  
print("hello world!")  
zhubenshuli@raspberrypi /var/www/lua_program $ sudo chmod +x hello.lua  
zhubenshuli@raspberrypi /var/www/lua_program $ ./hello.lua  
hello world!  

—|—

语法

1.注释

1  
2  
3  
4  
5  
    这是神奇的块注释  
--]]  

—|—

2.变量
lua的变量没有特殊说明全是全局变量,变量前加local关键字的是局部变量。
可以这样访问全局变量(假设变量名为globalVar):

1  
2  
_G.globalVar  
_G["globalVar"]  

—|—

布尔类型是false的情况只有nilfalse
lua的数字只有double型,64bits

控制语句

while循环

 1  
2  
3  
4  
5  
6  
7  
8  
sum = 0;  
num = 1;  
while num <= 100 do  
    sum = sum + num  
    num = num + 1  
end  
  
print("sum =",sum)  

—|—

if-else分支

 1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
age = 50  
sex = "male"  
if age == 40 and sex == "male" then  
    print("男人四十一枝花")  
elseif age == 60 and sex ~= "female" then  
    print("old man without country!")  
elseif age < 20 then  
    io.write("too young too simple")  
else  
    local age = io.read()  
    print("your age is "..age)  
end  

—|—

不等于是~=
字符串的拼接操作符是..
条件语句中的与或非是:and、or、not

for循环

  • 从1加到100

    1   2   3   4  
    
    sum = 0  
for i = 1, 100 do  
    sum = sum + i  
end  

—|—

  • 从1到100的奇数和

    1   2   3   4  
    
    sum = 0  
for i = 1, 100, 2 do  
    sum = sum + i  
end  

—|—

until循环

 1  
2  
3  
4  
5  
sum = 2  
repeat  
    sum = sum ^ 2   
    print(sum)  
until sum > 1000  

—|—

函数

递归

 1  
2  
3  
4  
function (n)  
    if n < 2 then return 1 end  
    return fib(n-2) + fib(n-1)  
end  

—|—

闭包

 1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
function newCounter()  
    local i = 0  
    return function()  
        i = i + 1  
        return i  
    end  
end  
  
cl = newCounter()  
print("cl() = "..cl())    
print("cl() = "..cl())  -- cl() = 2  

—|—

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
function myPower(x)  
    return function(y)  
        return y^x  
    end  
end  
  
power2 = myPower(2)  
power3 = myPower(3)  
  
print("power2(4) = "..power2(4))    -- 4的2次方  
print("power3(5) = "..power3(5))    -- 5的3次方  

—|—

函数的返回值
函数可以返回多个值

1  
2  
3  
4  
5  
function getUserinfo()  
    return "xqd", "25", "php"  
end  
  
name, age, profession = getUserinfo()  

—|—

Table

table是一个KEY VALUE的数据结构:
zhubenshuli = {name="xqd", age=25, handsome=false}
遍历table

1  
2  
3  
for k, v in pairs(zhubenshuli) do  
    print(k, v)  
end  

—|—

tableCRUD操作:

1  
2  
3  
4  
zhubenshuli.github = "https://github.com/zhubenshuli"  
zhubenshuli.name = nil  
zhubenshuli.handsome = true  
age = zhubenshuli.age  

—|—

也可以这样定义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  
2  
3  
for i=1, #arr do  
    print(arr[i])  
end  

—|—

MetaTable和MetaMethod

MetaTable主要用来做一些类似于C++重载操作符式的功能。
比如,有两个分数:

1  
2  
fraction_a = {numeractor=2, denominator=3}  
fraction_b = {numeractor=4, denominator=7}  

—|—

要实现两个分数的相加:2/3+4/7,就要动用MetaTable

1  
2  
3  
4  
5  
6  
7  
fraction_op = {}  
function fraction_op.__add(f1, f2)  
    ret = {}  
    ret.numeractor = f1.numeractor*f2.denominator+f1.denominator*f2.numeractor  
    ret.denominator = f1.denominator*f2.denominator  
    return ret  
end  

—|—

为之前定义的两个table设置MetaTable

1  
2  
setmetatable(fraction_a, fraction_op)  
setmetatable(fraction_b, fraction_op)  

—|—

最后就可以实现两个table相加了:

1  
fraction_c = fraction_a + fraction_b  

—|—

__addMetaMethod,这是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的操作。
如果我们有两个对象ab,想让b作为aprototype只需要:
setmetatable(a, {__index = b})
实例:用一个Window_Prototype的模板加上__indexMetaMethod来创建另一个实例:

1  
2  
3  
Window_Prototype = {x=0, y=0, width=100, height=100}  
MyWin = {title="hello"}  
setmetatable(MyWin, {__index = Window_Prototype})  

—|—

于是MyWin就可以访问xwidth等等了。
注:当表要索引一个值如table[key],lua会先在table本身中查找key的值,如果没有并且这个table存在一个带_index属性的MethTable,则lua会按照__index所定义的函数逻辑去查找。

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
Person = {}  
  
function Person:new(p)  
    local obj = p  
    if(obj == nil) then  
        obj = {name="xqd", age=25, handsome=true}  
    end  
    self.__index = self  
    return setmetatable(obj, self)  
end  
  
function Person:toString()  
    return self.name.." : "..self.age.." : "..(self.handsome and "handsome" or "ugly")  
end  

—|—

从上面我们可以看到一个new方法和toString方法,其中
1.self就是PersonPerson:new(p)相当于Person.new(self,p)
2.new方法的self.__index=self的意图是怕self被扩展后改写,让其保持原样
3.setmetatable这个函数返回的是第一个参数的值
可以这样调用:

1  
2  
3  
4  
5  
me = Person:new()  
print(me:toString())  
  
kf = Person:new({name="King's fucking", age=80, handsome=false})  
print(kf:toString())  

—|—

继承如下:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
Student = Person:new()  
  
function Student:new()  
    newObj = {year=2015}  
    self.__index = self  
    return setmetatable(newObj, self)  
end  
  
function Student:toString()  
    return "Student:"..self.name..", "..self.year  
end  

—|—

模块

可以直接使用requite("model_name")来载入别的lua文档,文档的后缀名是.lua,载入的时候就直接执行那个文档了。
注意:
1.require函数,载入同样的lua文档时,只有第一次的时候去执行,后面相同的都不执行了。
2.如果要让每一次文档载入都执行的话,可以使用dofile("model_name.lua")函数
3.载入后在需要的时候执行,可以使用loadfile函数。如:

1  
2  
3  
4  
local hello = loadfile("model_name.lua")  
...  
...  
hello()  

—|—

正常用法如下:
mymod.lua内容如下:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
local xqdModel = {}  
  
local function getname()  
    return "xqd"  
end  
  
function xqdModel.Greeting()  
    print("hello, my name is "..getname())  
end  
  
return xqdModel  

—|—

然后就可以这样使用:

1  
2  
local xqd_model = require("mymod")  
xqd_model.Greeting()  

—|—

糖果

糖果
LUA教程

Lapis框架的常用处理方法

Lapis框架的常用处理方法 Continue reading

MoonScript实现选择排序

Published on February 26, 2017

MoonScript与Redis客户端

Published on January 19, 2017