初步印象
- 语法和python、js这些很像,解释型语言、弱类型等等。写着舒服是真的。
- while do\repeat until这样的语法其实真心不舒服,感觉在语法上有些累赘。大多数语言都是do while,但是它非要是repeat until,也是无语。
- 我个人认为语法中的then和do设计的很混淆。比如if是和then,for是和do。从我对语言的理解上感觉可以统一用do或者then。
基本语法
变量
- 只有布尔、字符串、数字、table和nil。但是没有一个明确的类型定义,完全按照赋值来进行推断。
- 默认是public,如果想private需要变量前加local。
- 可以一次性多复制,如果变量和值不对称,没有复制的变量为nil。
1 | a,b,c = 1,2 |
作用域
- 在lua中一个local变量的作用域可以是在一个循环中或者在一段if代码中。也可以是贯穿整个的table中(感觉table在某种角度完全可以看做是一个类)。但是如果你想控制一个local变量的值作用域某个区间,那么可以使用
do end
来明确划分一个block。下面这个例子的结果是nil,因为x在作用域只在do end
之间。但是这个不适用于全局变量,需要注意。
1 | do |
- 对比一下下面两段代码的不同结果。其实尽可能的不要出现变量同名的情况,尤其是第二段代码的行为可能不是我们想要的。
1 | x = 1 |
1 | x = 1 |
- 关于
do end
还有个用法,在lua中return和break需要在end\else\until之前(发现在print之前也可以),否则编译会出错。此时就需要do end
来包住return了。
1 | function boo() |
循环
- for\while do\repeat until,最后一个对象do while。
- for分为数值型和泛型:
1 | -- var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,如果不指定,默认为1。 |
1 | for i,v in ipairs(a) |
- for的循环中没有continue,这样导致了在for中可能出现if嵌套if的情况,因为没办法通过拆解if来实现简练的代码。不爽!!另外lua的
迭代
需要注意pairs 和 ipairs异同
同:都是能遍历集合(表、数组)
异:ipairs 仅仅遍历值,按照索引升序遍历,索引中断停止遍历。即不能返回 nil,只能返回数字 0,如果遇到 nil 则退出。它只能遍历到集合中出现的第一个不是整数的 key。
pairs 能遍历集合的所有元素。即 pairs 可以遍历集合中所有的 key,并且除了迭代器本身以及遍历表本身还可以返回 nil。
1 | Demo1: |
table
概念
table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数字、字典等。
Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。
Lua table 是不固定大小的,你可以根据自己需要进行扩容。
- 上面是runoob.com的lua教程中对table的描述。在我看来很难去描述table是个什么东西,但是我们可以通过对它的使用来总结它所扮演的一些角色,或者说什么场景下table能够作为什么来使用。
- 看下第二条,table中索引可以是任何类型的值,所以索引是个table也是可以的。但是必须不是nil,所以
look = {[www] = "ok"} 这样是不对的,www没有赋值,所以默认为nil因此出错table index is nil
常见用法
- 数组 : table一个典型的用法就是作为其它语言中的数组
1 | str = { 1,2,3} |
- 字典 : 也是常见的用法
1 | str = {name="Sai",age=33} |
table使用中容易出现的问题
- 看下这段代码
1 | temp = 1 |
- why?第一个print中为何结果不是1,因为tab[]这个用法的参数是key,而像11这样没有显示定义key的value默认的key就是1,所以这句话认为是输出key=1的value了。而且从遍历看居然只有一个数据,也就是说value 1的数据被替换掉了。
- 那么怎么让这个1显示出来呢?以我目前掌握的只能是改temp的值。
- 总结一下就是注意三点:
第一,所有元素之间,总是用逗号 “,” 隔开;
第二,所有索引值都需要用 “[“和”]”括起来;如果是字符串,还可以去掉引号和中括号; 即如果没有[]括起,则认为是字符串索引
第三,如果不写索引,则索引就会被认为是数字,并按顺序自动从 1往后编;
数组(lua叫table)下标从1开始,有点不习惯。
判断table是否是空(参考)
1 | a={2} |
字符串
..
是字符串相加,my god…- 对于string的处理,除了用string.xxx(strArg)这样的方式外,还可以用strArg:xxx的方法。
函数
- function可以返回也可以不返回结果,在定义时没有明确的约束。
- 支持多返回值,nice
- Lua函数不支持参数默认值,可以通过or来实现。
1 | function sum(a , b) |
- 支持闭包
1 | tab = {1,2,3,4,5,6,7,8} |
- 可变参数,这里有点小特别:
Lua将函数的参数放在一个叫arg的表中,#arg 表示传入参数的个数。
1 | function average(...) |
这个#还能来取table中元素的个数,但是使用限制比较大。建议还是开启循环来计算个数。
:
和.
的区别:是个语法糖,调用的函数会自动传递参数self,即:
1 | local a = {x = 0} |
- 需要注意的是如果一个table中的方法调local的非table方法(简单来说就是一个类方法要访问非类方法)需要将非类的方法定义在前面,这个和C的机制一样。同样的,非类方法之间的调用也要有顺序,都尼玛血泪的教训
API
- 标准库的API可以在这里查询到。
- math.random的行为很是奇怪,一次调用永远产生相同的值。如果想得到不同的值,需要多次调用。
- 对于table等的操作建议看参考2的连接。