lua学习笔记
lua特性总结:
- lua可以多重赋值,同时函数可以有多个返回值
- lua函数是一种first-class value
- lua函数可以嵌套,closure的概念
- 元表、元方法
- 注释
--:行注释 --[[ ]]: 块注释 小技巧: 注释代码: --[[ 代码 --]] 重新启用这段代码: ---[[ 代码 --]]
- 全局变量:将一个值赋予一个全局变量就创建了该全局变量(访问一个未创建的全局变量得到的值为nil);删除一个全局变量,只需将其赋值为nil
- 基础类型:
1.nil(空): 用于区别其它任何值; 可用于表示一种“无效值”的情况;
2.boolean(布尔): false和true; Lua将值false和nil视为“假”,其它视为真;
3.number(数字): 用来表示实数; 合法的表示方法:4、0.4、4.57e-3;
4.string(字符串): 字面字符串以一对匹配的单引号或双引号来界定; lua提供了字符串和数字的自动转换; 手动转换: 字符串转数字:tonumber(); 数字转字符串:tostring();或者将该数字与一个空字符串相连接(number .. "")(..是字符串连接操作符); #:长度操作符,放在字符串的前面,用于获取字符串的长度;
5.table(表): 最简单的构造表达式:a = {}; table永远是匿名的,只能通过引用来持有table,当一个table的引用计数为0时,lua的垃圾收集器会删除该table; table可以用不同类型的索引来访问value; a.x:等同于a["x"]; a[x]:等同与a[变量x的值]; 数组通常以1做为索引的起始值; #:返回数组或线性表的最后一个索引值,以nil作为界定数组结尾的标志; table.maxn:返回一个table的最大正索引数;
6.function(函数):
7.userdata(自定义类型):
8.thread(线程):
- table构造式:
列表风格:a = {"Sunday", "Monday",},索引默认从1开始(print(a[1]) = "Sunday"),不能使用负数的索引; 记录风格:a = {x="Sunday", y="Monday"},等价于{["x"]="Sunday", ["y"]="Monday"}; 两种风格混合(中间用;隔开):a = {"Sunday", "Monday"; x="Sunday", y="Monday"};
- 多重赋值:
特性:首先匹配左右两边的赋值对象(丢掉多余的、用nil补充不足的);然后同时进行赋值操作(没有前后顺序之分)。 1.用于交换变量的值:a, b = b, a; 2.用于函数返回多个值
- 控制结构
1.if then + end 2.if then elseif then else + end 3.while do + end 4.repeat until(相当于C++里面的do while) 5.数字型for: for var=exp1, exp2, exp3 do end var从exp1变化到exp2,每次变化的步长为exp3,缺省为1,如果不想设置上限的话,可以使用常量math.huge; 6.泛型for: for <var-list> in <exp-list> do <body> end 通常exp-list只有一个元素,即一句对迭代器工厂的调用; 如:for k, v in pairs(t) do print(k, v) end; var-list第一元素称为控制变量,当它为nil时,循环结束; for做的第一件事情是对exp-list求值,for会保存三个值:迭代器函数、恒定状态、控制变量初值; 在初始化步骤之后,for会以恒定状态和控制变量来调用迭代器函数,然后for将迭代器函数的返回值赋予变量列表中的变量。如果第一个返回值为nil,那么循环终止。否则,执行循环体,并重复这个过程。 for var_1, ..., var_n in <exp-list> do <block> end 等价于: do local _f, _s, _var = <explist> while true do local var_1, ..., var_n = _f(_s, _var) _var = var_1 if _var==nil then break end <block> end end
- 变长参数:
function add(...) local s = 0 for i, v in ipairs{...} do s = s+v end return s end print(add(3, 4, 10, 25, 12)) 参数中的...表示函数可接受不同数量的参数; 函数要访问它的参数时,需要通过...来获得; 如果变长参数中包含nil,则需要用函数select来访问变长参数; 调用select时,必须传入一个selector和变长参数列表。如果selector为数字n,则返回它的第n个可变实参;如果selector为字符串“#”,则返回变长参数的总数(包含nil); for i=1, select("#", ...) do local arg = select(i, ...) -- 得到第i个参数 <body> end
- 具名参数:把函数形参列表放入到一个table中,调用函数时传入实参table
- 函数是一种第一类值(first-class value):表示lua中的函数与其它传统类型具有相同的地位。可以存储到变量或table中,可以作为实参传递给函数,可以作为函数的返回值
- 词法域(lexical scoping):一个函数可以嵌套到另一个函数中,内部的函数可以访问外部函数中的局部变量(external local value / upvalue)
- 闭包函数(closure):是指一个函数及一系列这个函数会访问到的upvalue。因此,若一个closure没有访问到upvalue,那它就是一个传统意义上的函数
- 元表、元方法:
元表是元方法的集合,设置方法setmetatable(tablename, metatable); 元方法是自定义的操作集合,相当于C++中的操作符重载; 算术类的元方法: +: __add -: __sub *: __mul /: __div -: __unm(相反数) %:__mod ^: __pow 关系类的元方法: ==:__eq <: __lt <=: __le 库定义的元方法: print():__tostring __metatable:用于保护集合的元表,使用户既不能看也不能修改集合的元表 __index元方法: 用于集合的查询,当访问table中不存在的字段时,解释器就会去查找一个叫__index的元方法; __newindex元方法: 用于集合的更新,当更新table中不存在的字段时,解释器就会去查找一个叫__newindex的元方法; 具有默认值的table: v1: function setDefault(t, d) local mt = {__index = function() return d end} setmetatable(t, mt) end v2: key = {} local mt = {__index = function(t) return t[key] end} function setDefault(t, d) t[key] = d setmetatable(t, mt) end