print("Hello World") --Hello World
Lua 中,换行不起任何作用。如果愿意,可以用分号分隔语句。
标识符和 C 一样,可以包含字母数字下划线,不能数字开头。尽量避免下划线跟着一串大写字母,Lua将其保留用作特殊用途。
P4 Lua 保留字
--这是行注释 --[[ 这是块注释 --]] --若想要重新启用块注释的代码 ---[[ --在块注释的第一行加一个连字符即可 print(10) --]]
不需要声明,如果未初始化,结果是 nil
print(b) --nil b = 10 print(b) --10 b = nil --如果要删除全局变量,将其赋值为nil print(b) --nil
在运行脚本前,会用所有的命令行参数创建一个名为 arg 的 table,脚本名称在索引 0 上,第一个参数位于索引 1,脚本之前的选项参数位于负数索引上
有八种基础类型:nil,boolean,number,string,userdata,function,thread,table
--type函数返回类型名称(返回值是string类型) print(type("Hello")) --> string print(type(type(42))) --> string a = print --可以像操作别的值那样操作函数值 a(type(a)) --function
是一种类型,只有一个值 nil,用于区别其他任何值。用于表示无效值的情况。
false 和 nil 视为假,其他所有值都是真,所以数字零和空字符串也是真
用于表示实数。lua 没有整数类型。
--可以使用科学计数法 print(5e+10) -->50000000000
Lua 的字符串是不可变的值,并且是自动内存管理机制所管理的对象,无需担心字符串的分配和释放。
--字面字符串用单双引号皆可 a = "a line" b = 'another line' --可以包含类似C的转义序列 c = "hi\nhello" --可以用转义序列,通过数值指定字符 d = "hi\065hello" print(d) -->hiAhello --用双方括号界定字符串,不会解释转义序列 --回忽略第一个换行符 e = [[ first second ]] --如果字符串中出现]] --可以在前后的双方括号之间加上数量相等的等号 --对块注释同样适用 f = [===[ first a[b[]] ]===]
数字和字符串存在自动转换
print("10" + 1) -->11 print("10" * "2") -->20 -- ..是字符串连接符 print(10 .. 20) -->1020 --用函数显式转换 print(tonumber("100") * 30) -->3000 print(tostring(12.45) .. "hello") -->12.45hello -- #是长度操作符 print(#(tostring(12.45) .. "hello")) -->10
实现了关联数组
a = {} --创建table a[5] = 6 a["index"] = 100 print(a[5]) print(a["index"]) print(a.index) --语法糖,注意只有字符串索引可以这么用 --table是一种动态分配的对象,程序仅持有一个对它们的引用(指针) b = a b[5] = 1000 print(a[5]) -->1000 b = nil --只有a还在引用table a = nil --没有对table的引用了 --此时Lua的垃圾收集器自动删除table,回收内存
如果要表示传统的数组,用整数 key 即可:
a = {} for i = 1, 10 do a[i] = i end for i = 1, 10 do print(a[i]) end --在Lua的习惯中,数组通常以1作为索引起始值
长度操作符的习惯用法:
print(a[#a]) --打印最后一个值 a[#a] = nil --删除最后一个值 a[#a+1] = 100 --把100加到列表末尾
对于包含空隙的数组,长度操作符会出问题
a = {} a[1000] = 6; print(#a) -->0 --可以使用table.maxn,返回table的最大正索引数 print(table.maxn(a)) -->1000
函数可以存储在变量中,可以通过参数传递给其他函数,可以作为函数的返回值。程序可以重新定义函数,或者删除某些函数。
userdata 将任意 C 语言数据存储到 lua 变量中,只能进行赋值和相等性测试。
thread 详见第 9 章
二元:+ 加 - 减 * 乘 / 除 ^ 指数 % 取模
一元:- 负号
其中,取模的定义如下:
a % b == a - floor(a/b)*b
对于整数,计算结果的符号与第二个参数相同
对于实数,x%1 得到小数部分,x-x%0.01 是 x 精确到小数点后两位的结果
< > <= >= == ~=
全部返回 true 或者 false
注意 == 和 ~= 可以用于任意两个值。如果类型不同则不相等。nil 只和自身相等
对于 table,userdata,Lua 作引用比较
对于字符串和数字的大小比较会引发一个错误。
and or not
false 和 nil 视为假,其他都是真
对 and,如果第一个操作数为假,返回第一个操作数,否则返回第二个
对 or,如果第一个操作数为真,返回第一个操作数,否则返回第二个
and 和 or 都使用短路求值,类似 cpp
x = x or v --等价于 if not x then x = v end max = (x > y) and x or y --等价于c中的 --max = x > y ? x : y --前提是x不为假
not 永远只返回 true 或者false
… 操作符。因为 Lua 中字符串是不可变的,因此连接操作符只会创建一个新的字符串
P22
指数操作符和连接操作符是右结合的,其他都是左结合的。
--a[1] = "A",以此类推 a = {"A", "B", "C"} for i = 1, #a do print(a[i]) end
特殊的语法:
a = {x = 10, y = 20} print(a.x == 10) -->true
每当 Lua 处理构造式,会先创建新的 table 然后初始化它。用 Lua 新建链表的代码:
list = nil for line in io.lines() do list = {next = list, value = line} end -- 输出 local l = list while l do print(l.value) l = l.next end
注意,真实的 Lua 程序很少使用链表。
更通用的格式如下:
opnames = {["+"] = "add", ["-"] = minus} --可以嵌套 polyline = {color = "blue", {x = 5, y = 10}} --等价于 polyline = {["color"] = "blue", {["x"] = 5, ["y"] = 10}}
在构造是中可以用分号代替逗号,功能没有不同,可以加强可读性