LUA要点笔记<一>
摘自《Programming in LUA》,着重选一些特点。PS:谁能提供一本实例教程?
全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初
始化的全局变量也不会出错,只不过得到的结果是:nil.
-e:直接将命令传入Lua
prompt> lua -e "print(math.sin(12))" --> -0.53657291800043
-l:加载一个文件.
-i:进入交互模式.
第2 章 类型和值
Lua 是动态类型语言,变量不要类型定义。Lua 中有8 个基本类型分别为:nil、boolean、
number、string、userdata、function、thread 和table。函数type 可以测试给定变量或者值
的类型。
两个取值false 和true。但要注意Lua 中所有的值都可以作为条件。在控制结构的条
件中除了false 和nil 为假,其他值都为真。所以Lua 认为0 和空串都是真。
第3 章 表达式
a and b -- 如果a为false,则返回a,否则返回b
a or b -- 如果a为true,则返回a,否则返回b
一个很实用的技巧:如果x 为false 或者nil 则给x 赋初始值v
x = x or v
等价于
if not x then
x = v
end
and 的优先级比or 高。
not 的结果一直返回false 或者true
print(not nil) --> true
逻辑运算符认为false 和nil 是假(false),其他为真,0 也是true.
and 和or 的运算结果不是true 和false,而是和它的两个操作数相关。
a and b -- 如果a为false,则返回a,否则返回b
a or b -- 如果a为true,则返回a,否则返回b
例如:
print(4 and 5) --> 5
print(nil and 13) --> nil
print(false and 13) --> false
print(4 or 5) --> 4
print(false or 5) --> 5
一个很实用的技巧:如果x 为false 或者nil 则给x 赋初始值v
x = x or v
等价于
if not x then
x = v
end
and 的优先级比or 高。
C 语言中的三元运算符
a ? b : c
在Lua 中可以这样实现:
(a and b) or c
not 的结果一直返回false 或者true
print(not nil) --> true
print(not false) --> true
print(not 0) --> false
print(not not nil) --> false
连连接接运运算算符符
.. --两个点
字符串连接,如果操作数为数字,Lua 将数字转成字符串。
print("Hello " .. "World") --> Hello World
print(0 .. 1) --> 01
w = {x=0, y=0, label="console"}
x = {sin(0), sin(1), sin(2)}
w[1] = "another field"
x.f = w
print(w["x"]) --> 0
print(w[1]) --> another field
print(x.f[1]) --> another field
w.x = nil -- remove field "x"
在构造函数中域分隔符逗号(",")可以用分号(";")替代,通常我们使用分号用来
分割不同类型的表元素。
{x=10, y=45; "one", "two", "three"}
print(not false) --> true
print(not 0) --> false
print(not not nil) --> false
第4 章 基本语法
Lua 可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语
句右边的值会依次赋给左边的变量。
a, b = 10, 2*x <--> a=10; b=2*x
遇到赋值语句Lua 会先计算右边所有的值然后再执行赋值操作,所以我们可以这样
进行交换变量的值:
x, y = y, x -- swap 'x' for 'y'
a[i], a[j] = a[j], a[i] -- swap 'a[i]' for 'a[i]'
当变量个数和值的个数不一致时,Lua 会一直以变量个数为基础采取以下策略:
a. 变量个数>值的个数 按变量个数补足nil
b. 变量个数<值的个数 多余的值会被忽略
例如:
a, b, c = 0, 1
print(a,b,c) --> 0 1 nil
a, b = a+1, b+1, b+2 -- value of b+2 is ignored
print(a,b) --> 1 2
a, b, c = 0
print(a,b,c) --> 0 nil nil
多值赋值经常用来交换变量,或将函数调用返回给变量:
a, b = f()
f()返回两个值,第一个赋给a,第二个赋给b。
我们给block 划定一个明确的界限:do..end 内的部分。
控制结构的条件表达式结果可以是任何值,Lua 认为false 和nil 为假,其他值为真。
repeat-until 语句:
repeat
statements;
until conditions;
有时候为了调试或者其他目的需要在block 的中间使用return 或者break,可以显式
的使用do..end 来实现:
function foo ()
return --<< SYNTAX ERROR
-- 'return' is the last statement in the next block
do return end -- OK
... -- statements not reached
end
调用函数的时候,如果参数列表为空,必须使用()表明是函数调用。
print(8*9, 9/8)
a = math.sin(3) + math.cos(10)
print(os.date())
上述规则有一个例外,当函数只有一个参数并且这个参数是字符串或者表构造的时
候,()是可选的:
print "Hello World" <--> print("Hello World")
dofile 'a.lua' <--> dofile ('a.lua')
print [[a multi-line <--> print([[a multi-line
message]] message]])
f{x=10, y=20} <--> f({x=10, y=20})
type{} <--> type({})
Lua 函数实参和形参的匹配与赋值语句类似,多余部分被忽略,缺少部分用nil 补足。
function f(a, b) return a or b end
CALL PARAMETERS
f(3) a=3, b=nil
f(3, 4) a=3, b=4
f(3, 4, 5) a=3, b=4 (5 is discarded)
Lua 函数中,在return 后列出要返回的值得列表即可返回多值,如:
function maximum (a)
local mi = 1 -- maximum index
local m = a[mi] -- maximum value
for i,val in ipairs(a) do
if val > m then
mi = i
m = val
end
end
return m, mi
end
print(maximum({8,10,23,12,5})) --> 23 3
Lua 总是调整函数返回值的个数去适用调用环境,当作为一个语句调用函数时,所
有返回值被忽略。假设有如下三个函数:
function foo0 () end -- returns no results
function foo1 () return 'a' end -- returns 1 result
function foo2 () return 'a','b' end -- returns 2 results
第一,当作为表达式调用函数时,有以下几种情况:
1. 当调用作为表达式最后一个参数或者仅有一个参数时,根据变量个数函数尽可能
多地返回多个值,不足补nil,超出舍去。
2. 其他情况下,函数调用仅返回第一个值(如果没有返回值为nil)
x,y = foo2() -- x='a', y='b'
x = foo2() -- x='a', 'b' is discarded
x,y,z = 10,foo2() -- x=10, y='a', z='b'
x,y = foo0() -- x=nil, y=nil
x,y = foo1() -- x='a', y=nil
x,y,z = foo2() -- x='a', y='b', z=nil
x,y = foo2(), 20 -- x='a', y=20
x,y = foo0(), 20, 30 -- x='nil', y=20, 30 is discarded
第二,函数调用作为函数参数被调用时,和多值赋值是相同。
print(foo0()) -->
print(foo1()) --> a
print(foo2()) --> a b
print(foo2(), 1) --> a 1
print(foo2() .. "x") --> ax
第三,函数调用在表构造函数中初始化时,和多值赋值时相同。
a = {foo0()} -- a = {} (an empty table)
a = {foo1()} -- a = {'a'}
a = {foo2()} -- a = {'a', 'b'}
a = {foo0(), foo2(), 4} -- a[1] = nil, a[2] = 'a', a[3] = 4
另外,return f()这种类型的返回f()返回的所有值
function foo (i)
if i == 0 then return foo0()
elseif i == 1 then return foo1()
elseif i == 2 then return foo2()
end
end
print(foo(1)) --> a
print(foo(2)) --> a b
print(foo(0)) -- (no results)
print(foo(3)) -- (no results)
可以使用圆括号强制使调用返回一个值。
print((foo0())) --> nil
print((foo1())) --> a
print((foo2())) --> a
全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初
始化的全局变量也不会出错,只不过得到的结果是:nil.
-e:直接将命令传入Lua
prompt> lua -e "print(math.sin(12))" --> -0.53657291800043
-l:加载一个文件.
-i:进入交互模式.
第2 章 类型和值
Lua 是动态类型语言,变量不要类型定义。Lua 中有8 个基本类型分别为:nil、boolean、
number、string、userdata、function、thread 和table。函数type 可以测试给定变量或者值
的类型。
两个取值false 和true。但要注意Lua 中所有的值都可以作为条件。在控制结构的条
件中除了false 和nil 为假,其他值都为真。所以Lua 认为0 和空串都是真。
第3 章 表达式
a and b -- 如果a为false,则返回a,否则返回b
a or b -- 如果a为true,则返回a,否则返回b
一个很实用的技巧:如果x 为false 或者nil 则给x 赋初始值v
x = x or v
等价于
if not x then
x = v
end
and 的优先级比or 高。
not 的结果一直返回false 或者true
print(not nil) --> true
逻辑运算符认为false 和nil 是假(false),其他为真,0 也是true.
and 和or 的运算结果不是true 和false,而是和它的两个操作数相关。
a and b -- 如果a为false,则返回a,否则返回b
a or b -- 如果a为true,则返回a,否则返回b
例如:
print(4 and 5) --> 5
print(nil and 13) --> nil
print(false and 13) --> false
print(4 or 5) --> 4
print(false or 5) --> 5
一个很实用的技巧:如果x 为false 或者nil 则给x 赋初始值v
x = x or v
等价于
if not x then
x = v
end
and 的优先级比or 高。
C 语言中的三元运算符
a ? b : c
在Lua 中可以这样实现:
(a and b) or c
not 的结果一直返回false 或者true
print(not nil) --> true
print(not false) --> true
print(not 0) --> false
print(not not nil) --> false
连连接接运运算算符符
.. --两个点
字符串连接,如果操作数为数字,Lua 将数字转成字符串。
print("Hello " .. "World") --> Hello World
print(0 .. 1) --> 01
w = {x=0, y=0, label="console"}
x = {sin(0), sin(1), sin(2)}
w[1] = "another field"
x.f = w
print(w["x"]) --> 0
print(w[1]) --> another field
print(x.f[1]) --> another field
w.x = nil -- remove field "x"
在构造函数中域分隔符逗号(",")可以用分号(";")替代,通常我们使用分号用来
分割不同类型的表元素。
{x=10, y=45; "one", "two", "three"}
print(not false) --> true
print(not 0) --> false
print(not not nil) --> false
第4 章 基本语法
Lua 可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语
句右边的值会依次赋给左边的变量。
a, b = 10, 2*x <--> a=10; b=2*x
遇到赋值语句Lua 会先计算右边所有的值然后再执行赋值操作,所以我们可以这样
进行交换变量的值:
x, y = y, x -- swap 'x' for 'y'
a[i], a[j] = a[j], a[i] -- swap 'a[i]' for 'a[i]'
当变量个数和值的个数不一致时,Lua 会一直以变量个数为基础采取以下策略:
a. 变量个数>值的个数 按变量个数补足nil
b. 变量个数<值的个数 多余的值会被忽略
例如:
a, b, c = 0, 1
print(a,b,c) --> 0 1 nil
a, b = a+1, b+1, b+2 -- value of b+2 is ignored
print(a,b) --> 1 2
a, b, c = 0
print(a,b,c) --> 0 nil nil
多值赋值经常用来交换变量,或将函数调用返回给变量:
a, b = f()
f()返回两个值,第一个赋给a,第二个赋给b。
我们给block 划定一个明确的界限:do..end 内的部分。
控制结构的条件表达式结果可以是任何值,Lua 认为false 和nil 为假,其他值为真。
repeat-until 语句:
repeat
statements;
until conditions;
有时候为了调试或者其他目的需要在block 的中间使用return 或者break,可以显式
的使用do..end 来实现:
function foo ()
return --<< SYNTAX ERROR
-- 'return' is the last statement in the next block
do return end -- OK
... -- statements not reached
end
调用函数的时候,如果参数列表为空,必须使用()表明是函数调用。
print(8*9, 9/8)
a = math.sin(3) + math.cos(10)
print(os.date())
上述规则有一个例外,当函数只有一个参数并且这个参数是字符串或者表构造的时
候,()是可选的:
print "Hello World" <--> print("Hello World")
dofile 'a.lua' <--> dofile ('a.lua')
print [[a multi-line <--> print([[a multi-line
message]] message]])
f{x=10, y=20} <--> f({x=10, y=20})
type{} <--> type({})
Lua 函数实参和形参的匹配与赋值语句类似,多余部分被忽略,缺少部分用nil 补足。
function f(a, b) return a or b end
CALL PARAMETERS
f(3) a=3, b=nil
f(3, 4) a=3, b=4
f(3, 4, 5) a=3, b=4 (5 is discarded)
Lua 函数中,在return 后列出要返回的值得列表即可返回多值,如:
function maximum (a)
local mi = 1 -- maximum index
local m = a[mi] -- maximum value
for i,val in ipairs(a) do
if val > m then
mi = i
m = val
end
end
return m, mi
end
print(maximum({8,10,23,12,5})) --> 23 3
Lua 总是调整函数返回值的个数去适用调用环境,当作为一个语句调用函数时,所
有返回值被忽略。假设有如下三个函数:
function foo0 () end -- returns no results
function foo1 () return 'a' end -- returns 1 result
function foo2 () return 'a','b' end -- returns 2 results
第一,当作为表达式调用函数时,有以下几种情况:
1. 当调用作为表达式最后一个参数或者仅有一个参数时,根据变量个数函数尽可能
多地返回多个值,不足补nil,超出舍去。
2. 其他情况下,函数调用仅返回第一个值(如果没有返回值为nil)
x,y = foo2() -- x='a', y='b'
x = foo2() -- x='a', 'b' is discarded
x,y,z = 10,foo2() -- x=10, y='a', z='b'
x,y = foo0() -- x=nil, y=nil
x,y = foo1() -- x='a', y=nil
x,y,z = foo2() -- x='a', y='b', z=nil
x,y = foo2(), 20 -- x='a', y=20
x,y = foo0(), 20, 30 -- x='nil', y=20, 30 is discarded
第二,函数调用作为函数参数被调用时,和多值赋值是相同。
print(foo0()) -->
print(foo1()) --> a
print(foo2()) --> a b
print(foo2(), 1) --> a 1
print(foo2() .. "x") --> ax
第三,函数调用在表构造函数中初始化时,和多值赋值时相同。
a = {foo0()} -- a = {} (an empty table)
a = {foo1()} -- a = {'a'}
a = {foo2()} -- a = {'a', 'b'}
a = {foo0(), foo2(), 4} -- a[1] = nil, a[2] = 'a', a[3] = 4
另外,return f()这种类型的返回f()返回的所有值
function foo (i)
if i == 0 then return foo0()
elseif i == 1 then return foo1()
elseif i == 2 then return foo2()
end
end
print(foo(1)) --> a
print(foo(2)) --> a b
print(foo(0)) -- (no results)
print(foo(3)) -- (no results)
可以使用圆括号强制使调用返回一个值。
print((foo0())) --> nil
print((foo1())) --> a
print((foo2())) --> a