lua 学习笔记
一、注释: 单行注释 “ -- ” 多行注释 ?" --[[ ?--]]" 在 lua 一个代码块 用 do end 来分界,相当于c语言中的 { }。 二、数据类型: lua中变量不需要申明,给一个变量赋值就相当于声明了一个全局变量,直接用一个没有初始化的变量则会得到值 nil。如果要取消一个变量也可以通过赋值 nil 来实现。局部变量则在变量前面加上 local 关键字。 1、nil lua中的特殊类型,它的值只有 nil ?未定义值 2、boolean ?bool值,lua 中只有 nil 和 false 为 条件假,其它都为真所以 0 和 空串也为真 3、number 数字,整数实数都是它 4、string 字符串: ? 4.1 字符串是不能修改的。 ?4.2 lua中字符串和数字会自动进行隐士转换,所以使用的时候要注意可以使用tonumber 或者 tostring 强制将 字符串转换成数字、或数字转换成字符串。 ?4.3 字符串可以用 双引号或者单引号括起来。 ?4.4 字符串也可以用 [[ ?]] 括起一个字符块,它会按字符块的原始格式保存,并且不会解释其中的转义字符。 如果在 其中包含 a[b[i]] 这中情况的话可以在 中括号中间加任意数量等号做区别 如? [==[ ? a[b[c]] 测试测试 ]==]? 4.5 可以用 #strVar 获取字符串长度如 print(#"adfadfadfadf") 5、userdata 可以将 C 数据存放在userdata 变量中,userdata 除了定义 赋值 和 相等比较外没有预定义操作。 6、function 函数,lua 中函数也是变量的一种类型 7、thread 线程,在第九部分详细介绍 8、table lua中table 是最为关键的一个数据类型,很多语言特性都由它实现,后面第七部分专门详细介绍 三、表达式: 数值运行:lua 支持 ?+ - * / ^ (加减乘除幂) 数值运算 关系运算: > 、 < 、 ?<= 、 >= 、 ?== 、 ~= ?。大于、小于、小于等于、大于等于、等于、不等于 逻辑运算: and、or、not。 注意lua 的 and、or 的返回值不是true和false而是操作数 not 返回值为boolean值 a and b -- 如果 a 为 false 返回 a ,否则返回 b a or b ? ?-- 如果 a 为 true 返回 a,否则返回 b c语言中的三元表达式 ?a ? b : c 可以用 ? ?((a ?and b ) or c ) ?实现。 连接运算符:lua中 .. 是连接字符串的连接操作符号。 表构造: lua 中 { } 是一个构造函数,用于构造表。 四、控制结构: 4.1?条件控制 ?: if conditions then elseif ? conditions then else end; 4.2?循环控制: 1、while循环 while condition do end 2、类似 do while repeat until ?conditions; 3、 for 版本一,和c区别在于,exp,exp2,exp3 表达式都是在运行前运算一次,循环从 var = exp1 到 exp2,增幅为exp3,。exp3默认为1 for var = exp1,exp2,exp3 do end 4、类似 foreach 循环读取容器中的内容 for ?k,v in ?pair(table) do ? ?-- 循环直到 ?k 为 nil? end 等价于 do local _f,_s,_var = explist -- _f 代表迭代函数、 _s 代表 要遍历的容器,_var 代表循环控制变量 while true do local var_1,...,var_n = _f(_s,_var) _var = var_1 if _var == nil then break end block end end 4.3 break 和 return? break 用于跳出循环用,return 用于函数返回用,lua 中 break 和 return 必须在 block的最后一句,所以有时候你得用 do break end; 这种写法。使它们在block的结尾。 五、函数 lua中函数申明方式为 function 函数名( 参数列表 ) 函数执行体 end 5.1 lua 中传参的 是普通变量为按值传递,对象类型为引用传递(table对象), 5.2 lua 中函数也是一种数据类型,所以可以直接将函数赋值给变量。 5.3 lua 中函数可以返回多个值, return 1,2,3; 这种是支持的。 5.4 lua 中支持可变的函数参数,和c 一样用 ... (三个点) 代表,然后访问这些参数是通过 arg 这个table来访问。 example: printResult = ?"" function print( ... ) for i,v in ipairs(arg) do printResult = printResult ... tostring(v); end end 5.4 lua 函数有尾调用的概念,当函数a的最后一个操作为单纯的调用一个函数b,那么lua在a调用完这个函数b后,不会再回到函数a调用b地方,也就是说,这时候伟调用有点象goto 语句了。它这种函数调用不会产生栈。 六、闭包 1、lua 中在一个函数中再定义一个函数,则内部函数可以访问外部函数函数的变量。 example: function funca() local aa = 10; function funcb() print(aa); -- funcb 中访问 funca 中定义的变量 aa end funcb(); end funca(); -- 将输出 102、当我们把函数内部在定义的函数作为返回值返回,且这个内部函数有使用外部函数中的变量,那么在内部函数中这个变量的相当于一个 c 语言中的 static 变量。 example: function newCounter() local i = 0; function returnfunc() i = i+1; print(i); end return returnfunc; end c = newCounter(); -- i 值被 函数 newCounter 初始化为 0 c(); -- 输出 1 c(); -- 输出 2 c1 = newCounter(); -- 由于 i 为 local 变量,所以再次调用 newCounter 时又会创建一个新的变量 i c1(); -- 输出 1 c(); -- 输出 3 c1(); -- 输出 2 7、Table ?table 类型实现了关联数组(std::map)。它可以使用除 nil 外的任意值做key索引。 特性: 1、table 是一个不是一个”值"也不是一个”变量“,而是“对象”,也就是说,table 的传递是按引用传递的。 ?2、Table 的构建用 ?{ } . ?2、Table 可以容纳 lua 中各种各样的元素,所以 lua 中 各种封装机制都通过 table 实现。 8、用 c 为 lua 编写包 lua中调用c 写的包,要将c编译成动态库,然后用 loadlib() 加载库,loadlib 函数第一个参数是库的路径,第二个参数是库的 初始化函数名字,成功loadlib 返回初始化库的函数,否则返回 nil。 9、Thread 协同,非抢占式多线程 1、coroutine.create( 过程函数 ) 创建一个协同 thread并返回,create 的参数是,协同thread的调用函数。 2、协同 thread 有三种状态,挂起、运行、停止。刚创建的协同是处于挂起状态的。 3、coroutine.status( 协同变量 ) 查看协同thread的当前状态 4、coroutine.resume( 协同变量 ) 让一个协同thread 从挂起状态转变成运行 5、coroutine.yield() ?在一个运行的协同过程函数中调用,将运行的协同挂起。 10、MetaMethods(相当于c++类的operator重定义) 在lua中可以使用 setmetatable 给 table 设置重定义operator 的metatable 表,用 getmetatable 可以获取一个table的 metatable。 metatable 可以重定义的操作有 1、 加 ? + ?<----> __add 2、减 -? <----> __sub 3、乘 *? <----> __mul 4、除 ? <----> __div 5、负 -? <----> __unm 6、幂 ^? <----> __pow 7、连接? ... ?<----> __conact 关系运算符metamethods 8、等于 == ?<----> __eq? 9、小于?< ?<----> __lt 10、小于等于 ?<=?? <----> __le 没有 ~= 不等、 大于>、大于等于 >= 这三个操作符,因为lua会遇到他们时会为我们自动转换成上面三种去操作。 库定义的metamethods 11、tostring ? ?tostring? <----> __tostring 12、缺失域 ? __index(获取缺失域的值) ? __newindex (给缺失域赋值) 一般情况下当访问 table 没有的域的时候是返回 nil 的。但是其实我们可以通过如下设置实现自定义回调。 1、给 table 的metatable的__index域指定一个遇到缺失域的时候的回调函数,函数原型是 function (table,key) ? functin (table,key,value) ?table 是缺失域的表,key 的缺失域的名字,value 是设置的值。 2、给 table 的metatable 的 __index 域指定一个 table,当遇到缺失的域时就到这个 指定的 table里面去找。 如果想对使用者隐藏metatable 可以将 metatable的 __metatable 域指定一个值,这样使用者getmetatable时返回这个值,使用者setmetatable时会出错。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |