Lua学习之路

打印hello world

创建 hello.lua 文件 添加以下代码
print("hello world")
使用lua解释器执行 % lua hello.lua

复杂一点的语法

返回输入数字的阶乘
function fact(n)
    if n == 0 then
        return 1
    else 
        return n * fact(n-1)
    end
end

print("enter a number:")
a = io.read("*number")   -- 读取一个数字(在lua中 -- 代表注释)
print(fact(a))

交互模式

终端输入 lua 进入交互模式

终端模式下命令

lua -e 后面可以直接跟代码,并执行代码
lua -e "print('hello lua')"
lua -i 后面跟lua脚本文件或者 -e 代码 执行完之后,会进入交互模式
lua -i -e "print('hello lua')"
如果lua -i -e  后面跟了一个名为'_PROMPT'的全局变量,则这个变量的值会作为
    交互模式的命令提示符

lua变量和块

lua所有的变量都是全局变量,除非使用local声明为局部变量。
在函数块里面声明的变量,只要没有加local也是全局变量。
局部变量是在语句块结束的时候删除。
在lua程序中访问局部变量的速度是比全局变量的速度快的。
lua局部变量的作用域是在对应的块内部
需要注意的是if ... else  ... end  是2个不同的代码块,里面的局部变量在if语句外部是拿不到的。

lua table

lua中数组和字典是没有做区分的。
a = {}
a = {1,2,3,4,5}
b = {"x":1,"y":2,"z":3}
print(a[1])  -- lua中是从1开始索引的
print(b["x"])
print(b.x)
可以通过赋值 nil 来让lua回收机制回收变量
print(a.x) 等同于  print(a["x"])

a = {}
x = "y"
a[x] = 10
print(a[x])  -- 10
print(a.x)  -- 相当于a["x"] nil
print(a.y)  -- 相当于a["y"] 10

polyline = { color = "blue", thickness=2,npoints=4,
{x = 0, y = 0 },
{x=-10,y=0},
{x=-10,y=1},
{x=0,y=1}
}
print(polyline[2].x)  --  -10
print(polyline[4].y)  --  1


opnames = {["+"] = "add", ["-"]= "sub", ["*"] = "mul", ["/"] = "div"}
i = 20 ; s = "-"
a = {[i+0] = s, [i+1] = s..s, [i+2] = s..s..s}
print(opnames[s])   -- sub
print(22)  --   ---

算数运算符

+-*/ % ^ 
取模的操作符定义规则
a%b == a - floor(a/b)*b
取一个整数的小数部分
a%1 
取整数部分
a - a%1

关系操作符

< > <= >=  ==  ~=

逻辑操作符

and  or not

nil

可以通过将变量赋值为nil,让lua回收变量

lua 元表

下面代码演示了对mytable表设置元表的方法
mytable = {}
mymetatable = {}
setmetatable(mytable, mymetatable)

上述代码也可以精简为一行
mytable = setmetatable({}, {})

获取对象的元表
getmetatable(mytable)  -- 返回mytable的元表

__index 元方法
这是metatable最常用的键
当你通过键访问mytable的时候,如果在mytable中没有你访问的键的值,那么lua就会寻找
mytable的metatable(如果有元表存在的话)中的__index键,如果__index包含一个表格
lua就会在表格中查找相应的键
other = {foo=1,[1]=2,"str"=3}
t = setmetatable({},{__index=other})
print(t.foo)  -- 1
print(t["foo"]) -- 1
print(t[1]) -- 2
print(t[2]) -- nil

例子2
mytable = setmetatable({key1 = "value1"},{__index=function(mytable,key)
    if key == "key2" then
        return "metatablevalue"
    else
        return nil
    end
end
})
print(mytable.key1,mytable.key2)
-- 输出结果为 value1   metatablevalue

table表的rawset和rawget方法

如果你使用了元表__index方法,那么查询的时候可能会在__index对应的table中查询值
如果你使用了元表__newindex方法,那么添加新的键值对的时候会执行__newindex对应元方法
如果我们不想触发上述两种机制,就可以使用rawget(tb,key)和rawset(tb,key,value)
__newindex元方法用来对表更新,如果表中已经存在这个键,那么会进行赋值操作,而不会调用元方法
如果表中不存在这个键,那么会调用元方法,并且该键不会保存,你可以通过在元方法中决定是否保存这个键值对

mymetatable = {}
mytable = setmetatable({key1 = "value1"}, {__newindex = mymetatable})

print(mytable.key1)    -- value1
mytable.newkey = "新值1"
print(mytable.newkey, mymetatable.newkey)  -- nil  新值1

mytable.key1 = "新值2"  
print(mytable.key1,mymetatable.key1)  -- "新值2"  nil


在元方法里面设置添加键值对
mytable = setmetatable({key1 ="value1"},{__newindex=function(mytable,key,value)
    rawset(mytable, key, "\"" .. value .. "\"")
end
})
mytable.key1 = "new value"
mytable.key2 = 4
print(mytable.key1,mytable.key2)  -- new value  "4"

lua赋值 =

x, y = y, x  -- 多重赋值加交换变量
lua多重赋值会将右边值的个数调整到与左边变量个数相一致。
原则:右边如果多余就舍弃,不足添加nil

lua标准库提供的迭代器

for i,v in ipairs(a) do print(v) end
for k in pairs(t) do print(k) end
以及其他迭代器
迭代文件中每行的(io.lines),迭代table元素的(pair),迭代数组元素的(ipairs),迭代字符串中单词的(string.gmatch)

函数和面向对象的调用

在lua中,函数是一种对语句和表达式进行抽象的主要机制。在调用
函数的时候都需要将所有参数放到一对圆括号中。即使调用函数时
没有参数,也必须写出一对空括号。只有一种特殊的例外情况:一
个函数若只有一个参数,并且此参数是一个字面字符串或table构造
式,那么圆括号就是可有可无的。
print "hello world"  等同于 print("hello world")
dofile "a.lua"   <--> dofile("a.lua")
f{x=10,y=20}  <--> f({x=10,y=20})

面向对象的调用也提供了一种特殊的语法——冒号操作符。
表达式o.foo(o,x) 的另一种写法是o:foo(x),冒号操作符使调用o.foo时
将o隐含地作为函数的第一个参数

多重返回值函数

s, e = string.find("hello lua users", "Lua")
print(s,e)  -- 7  9  返回匹配字符的开始和结束索引

协同程序

coroutine.create() -- 创建协同程序,参数是一个函数,当和resume配合使用的时候就唤醒函数调用
coroutine.resume() -- 重启coroutine,和create配合使用
coroutine.yield() -- 挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果
coroutine.status()  --查看coroutine的状态,coroutine有三种态:dead,suspend,runing
coroutine.wrap() -- 创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复
coroutine.running() -- 返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个coroutine的线程号

lua中的布尔类型

布尔类型只有nil和false是false,数字0和空字符串都是true
即if判断只有nil和false是假,其他都为真.
同样空字符串和空table也不是nil

你可能感兴趣的:(Lua学习之路)