--
单行注释
--
[
[
[多行注释
]
--
]
]
--
--
--
--
--
-
1.
变量
&
控制流
--
--
--
--
--
num
=
23
--
数字都是双精度
str
=
'aspythonstring'
--
像
Python
一样不可变
str
=
"aspythonuse"
--
可以双引号
str
=
[
[
像
Python
的多行注释可用于
表示多行字符串一样
方便
]
]
bol
=
nil
--
未定义;支持垃圾回收
--
缩进只为易读性,像
Matlab
一样以
end
结尾
while
num
<
50
do
num
=
num
+
1
--
没有
++
或
+=
自增操作符号
end
--
IF
条件开关
if
num
>
40
then
print
(
'> 40'
)
elseif
s
~
=
'aspython'
then
--
~
=
表示
!=
io
.
write
(
's is not aspython'
)
--
风骚的标准输出
else
thisIsGlobal
=
5
--
驼峰式命名
--
显示声明局部变量(像
Javascript
一样)
local
line
=
io
.
read
(
)
--
.
.
作为字符串连接符
print
(
'凛冬将至'
.
.
line
)
end
--
引用未定义变量将返回
nil
,这不是错误
foo
=
anUnknownVariable
--
等价于
foo
=
nil
aBoolValue
=
false
--
只有
nil
与
false
为逻辑假;
数字
0
与空字串
''
为真!
if
not
aBoolValue
then
print
(
'false'
)
end
--
像
Python
一样运用
'or'
和
'and'
--
得到
C
语言中
a
?
b
:
c
的效果;需注意
b
=
false
或
nil
的情况
ans
=
aBoolValue
and
'yes'
or
'no'
karlSum
=
0
for
i
=
1
,
100
do
--
像
Matlab
一样的递增语法,包括两端,如同数学中
[
1
,
100
]
karlSum
=
karlSum
+
i
end
--
Step
为
2
递减的方式
'100, 1, -2'
for
j
=
100
,
1
,
-
2
then
print
(
j
)
end
--
综上,范围可表示为
"begin, end [, step]"
--
另一个循环控制
num
=
23
repeat
print
(
'凡人必有一死'
)
num
=
num
-
1
until
num
==
0
--
--
--
--
--
-
2.
函数
--
--
--
--
--
function
fib
(
n
)
if
n
<
2
then
return
1
end
return
fib
(
n
-
2
)
+
fib
(
n
-
1
)
end
--
Javascript
一样的匿名函数与闭包
function
adder
(
x
)
--
返回一个函数
--
闭包内封存
x
值
return
function
(
y
)
return
x
+
y
end
end
a1
=
adder
(
9
)
a2
=
adder
(
36
)
print
(
a1
(
16
)
)
--
>
25
print
(
a2
(
64
)
)
--
>
100
--
遇到不匹配的列表长度时
--
过长的变量将被赋予
nil
--
过长的值将被忽略
x
,
y
,
z
=
1
,
2
,
3
,
4
--
4
将被忽略
function
bar
(
a
,
b
,
c
)
print
(
a
,
b
,
c
)
return
4
,
8
,
15
,
16
,
23
,
42
end
x
,
y
=
bar
(
'zaphod'
)
--
>
"zaphod nil nil"
--
x
=
4
,
y
=
8
,
其余值被忽略
--
函数与其他类型一样为一等公民
--
同样有
local
/
global
之分
--
像
Javascript
一样定义
function
f
(
x
)
return
x
*
x
end
f
=
function
(
x
)
return
x
*
x
end
print
'Hello World!'
--
只有一个
`字符串
`参数时可省略括号
--
--
--
--
--
-
3.
表
(
Table
)
--
--
--
--
--
--
表是
Lua
中唯一的复合类型
--
像
PHP
中的数组或
Javascript
中的
Object
一样
--
可用作
list
/
dict
/
map
--
默认以字符串作为
key
t
=
{
key1
=
'value1'
,
key2
=
false
}
--
像
Javascript
一样以
.
取值
print
(
t
.
key1
)
--
>
"value1"
t
.
key3
=
{
}
--
加入新的键值对
t
.
key2
=
nil
--
销毁一组键值对
--
理论上任何非
nil
的变量都可以作为
key
u
=
{
[
'@!#'
]
=
'qbert'
,
[
{
}
]
=
1729
,
[
6.28
]
=
'tau'
}
print
(
u
[
6.28
]
)
--
>
"tau"
a
=
u
[
'@!#'
]
--
a
=
'qbert'
b
=
u
[
{
}
]
--
b
=
nil;像
Javascript
一样
{
}
会创建新的对象
--
因此不要用蛋疼的
key
值,老老实实用字串或数字
--
同字符串一样,只有一个表作为函数的参数时可以省略括号
--
为了一个括号增加阅读难度,得不偿失
function
h
(
x
)
print
(
x
.
key1
)
end
h
{
key1
=
'Sonmi~451'
}
--
>
"Sonmi~451"
for
key
,
val
in
pairs
(
u
)
do
--
像
Python
一样的键值迭代
print
(
key
,
val
)
end
--
像
Javascript
一样的全局作用域
_G
print
(
_G
[
'_G'
]
==
_G
)
--
>
true
--
省略
key
之后即可变身为
list
--
实际上是以递增自然数为
key
v
=
{
'value1'
,
'value2'
,
1.21
,
'gigawatts'
}
for
i
=
1
,
#v do -- 像 Bash 一样,#v 表示列表长度
print
(
v
[
i
]
)
--
像
Matlab
一样,列表索引从
1
开始
end
--
--
--
--
--
-
3.1
Metatables
&
metamethods
--
--
--
--
--
--
元表
(
metatable
)就是表的表,像
Javascript
的原型
(
prototype
)一样
--
为表重载一些元方法
(
metamethods
)
f1
=
{
a
=
1
,
b
=
2
}
f2
=
{
a
=
2
,
b
=
3
}
--
s
=
f1
+
f2
为错
mm
=
{
}
function
mm
.
__add
(
x
,
y
)
sum
=
{
}
sum
.
a
=
x
.
a
+
y
.
a
sum
.
b
=
x
.
b
+
y
.
b
return
sum
end
setmetatable
(
f1
,
mm
)
setmetatable
(
f2
,
mm
)
--
实际调用
f1
的
metatable
中的
__add
(
f1
,
f2
)
--
只为
f1
设置元表也可以
s
=
f1
+
f2
--
s
=
{
a
=
3
,
b
=
5
}
--
s2
=
s
+
s
为错,
s
未定义元表
--
_
_index
元方法重载表中
key
的提取符号
`
.
`
defaultFavs
=
{
animal
=
'gru'
,
food
=
'donuts'
}
myFavs
=
{
food
=
'pizza'
}
setmetatable
(
myFavs
,
{
__index
=
defaultFavs
}
)
food
=
myFavs
.
food
--
Lua
中的值都具有元方法,只有
Table
可以重载
--
所有元方法如下
--
__add
(
a
,
b
)
for
a
+
b
--
__sub
(
a
,
b
)
for
a
-
b
--
__mul
(
a
,
b
)
for
a
*
b
--
__div
(
a
,
b
)
for
a
/
b
--
__mod
(
a
,
b
)
for
a
%
b
--
__pow
(
a
,
b
)
for
a
^
b
--
__unm
(
a
)
for
-
a
--
__concat
(
a
,
b
)
for
a
.
.
b
--
__len
(
a
)
for
#a
--
__eq
(
a
,
b
)
for
a
==
b
--
__lt
(
a
,
b
)
for
a
<
b
--
__le
(
a
,
b
)
for
a
<=
b
--
__index
(
a
,
b
)
<
fn
or
a
table
>
for
a
.
b
--
__newindex
(
a
,
b
,
c
)
for
a
.
b
=
c
--
__call
(
a
,
.
.
.
)
for
a
(
.
.
.
)
--
--
--
--
--
-
3.2
类风格的
Table
与继承
--
--
--
--
--
--
像
Javascript
一样并没有内置
Class
--
但可以通过
Table
`
{
}
`
实现
Dog
=
{
}
--
1.
function
Dog
:
new
(
)
--
2.
newObj
=
{
sound
=
'woof'
}
--
3.
self
.
__index
=
self
--
4.
return
setmetatable
(
newObj
,
self
)
--
5.
end
function
Dog
:
makeSound
(
)
--
6.
print
(
'I say '
.
.
self
.
sound
)
end
mrDog
=
Dog
:
new
(
)
--
7.
mrDog
:
makeSound
(
)
--
>
"I say woof"
--
1.
Dog
像类但实际是
Table
--
2.
Dog
:
new
(
.
.
.
)
:
=
Dog
.
new
(
self
,
.
.
.
)
--
3.
newObj
作
Dog
的实例
--
4.
self
是
Lua
中默认的参数,在这里
self
=
Dog
--
继承的时候可以改变
--
self
.
_
_index
与
self
的元方法
_
_index
不是一回事
--
self
=
{
__index
=
self
,
metatable
=
{
__index
=
.
.
.
}
}
--
5.
setmetatable
(
newObj
,
self
)
相当于
setmetatable
(
newObj
,
{
__index
=
self
}
)
--
赋予实例所有类方法
--
6.
同
2.
--
7.
mrDog
=
Dog
.
new
(
Dog
)
--
继承
LoudDog
=
Dog
:
new
(
)
function
LoudDog
:
makeSound
(
)
s
=
self
.
sound
.
.
' '
print
(
s
.
.
s
.
.
s
)
end
seymour
=
LoudDog
:
new
(
)
seymour
:
makeSound
(
)
--
>
"woof woof woof"
--
--
--
--
--
-
4.
模块
--
--
--
--
--
--
以下来自文件
mod
.
lua
local
M
=
{
}
local
function
sayMyName
(
)
print
(
'Hrunkner'
)
end
function
M
.
sayHello
(
)
print
(
'Why hello there'
)
sayMyName
(
)
end
return
M
--
以上
--
回到主文件
local
mod
=
require
(
'mod'
)
--
运行
mod
.
lua
中的代码
--
操作同下
local
mod
=
(
function
(
)
--
像
Javascript
一样
--
[
[
mod
.
lua
中的代码
]
]
--
end
)
(
)
mod
.
sayHello
(
)
--
>
"Why hello there"
mod
.
sayMyName
(
)
--
>
错!
sayMyName
(
)
是
mod
.
lua
中的局部变量
--
require
返回的值将被缓存
--
即使多次调用
require
被调用文件也只运行一次
--
mod2
.
lua
包含
print
(
"mod2"
)
local
a
=
require
(
"mod2"
)
--
>
"mod2"
local
b
=
require
(
"mod2"
)
--
不输出,
实际为
b
=
a
--
dofile
是不缓存的版本的
require
dofile
(
"mod2"
)
--
>
"mod2"
dofile
(
"mod2"
)
--
>
"mod2"
--
loadfile
读取文件但不执行
--
勘误:
f
=
loadfile
(
'mod2'
),需加后缀名,否则找不到文件
f
=
loadfile
(
'mod2.lua'
)
f
(
)
--
>
"mod2"
--
loadstring
读取代码字符串
f
=
loadstring
(
"print('Lua is cool!')"
)
f
(
)
--
>
"Lua is cool!"
--
--
--
--
--
-
5.
参考,略
--
--
--
--
--