打印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