0%

lua脚本学习

缘起

在看deepmind的论文的时候(笔记地址),去官网看论文的发现官方代码是用lua实现的,感觉也蛮合理,毕竟lua经常用来做游戏脚本,想想lua倒也蛮好玩,就去读读lua的基本语法,顺便读读deepmind官方的代码

入门

lua基本语法

打印helloworld就和python一样
print("Hello World!")

注释

单行注释

两个减号是单行注释:

1
--

多行注释

1
2
3
4
--[[
多行注释
多行注释
--]]

全局变量

当且仅当一个变量不等于nil时,这个变量即存在。

奇技淫巧

多行注释加 - 取消注释中间代码可以继续运行,单行注释没有此功能。

基本数据类型

nil

nil 作比较时应该加上双引号 "

boolean(布尔)

boolean 类型只有两个可选值:true(真) 和 false(假),Lua 把 false 和 nil 看作是 false,其他的都为 true,数字 0 也是 true:

string(字符串)

字符串由一对双引号或单引号来表示。

1
2
string1 = "this is string1"
string2 = 'this is string2'

也可以用 2 个方括号 “[[]]” 来表示”一块”字符串。
1
2
3
4
5
6
7
8
9
html = [[
<html>
<head></head>
<body>
<a href="http://www.runoob.com/">菜鸟教程</a>
</body>
</html>
]]
print(html)

字符串连接使用的是 ..
1
2
3
4
5
> print("a" .. 'b')
ab
> print(157 .. 428)
157428
>

使用 # 来计算字符串的长度,放在字符串前面,如下实例:
1
2
3
4
5
6
> len = "www.runoob.com"
> print(#len)
14
> print(#"www.runoob.com")
14
>

table

相当于python种的字典和集合
???啥叫associative arrays

Lua 中的表(table)其实是一个”关联数组”(associative arrays),数组的索引可以是数字或者是字符串。

函数

匿名函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- function_test2.lua 脚本文件
function testFun(tab,fun)
for k ,v in pairs(tab) do
print(fun(k,v));
end
end


tab={key1="val1",key2="val2"};
testFun(tab,
function(key,val)--匿名函数
return key.."="..val;
end
);

细节

使用 # 输出的值其实是字符串所占的字节数。当字符串为英文字符时,由于每个字符只占 1 个字节,所以输出结果等同于字符串长度

table 的索引不可以是数字,也不可以是字符串,会报错,只能是普通变量。

#实际上是

变量

  • 三种变量全局变量、局部变量、表中的域
  • Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量。

循环

while循环

1
2
3
4
while(condition)
do
statements
end

for循环

1
2
3
for var=exp1,exp2,exp3 do  
<执行体>
end

泛型for循环

1
2
3
4
5
--打印数组a的所有值  
a = {"one", "two", "three"}
for i, v in ipairs(a) do
print(i, v)
end

repeat…until 循环

类似do while

1
2
3
repeat
statements
until( condition )

流程控制

控制结构的条件表达式结果可以是任何值,Lua认为false和nil为假,true和非nil为真。

if条件语句

1
2
3
4
if(布尔表达式)
then
--[ 在布尔表达式为 true 时执行的语句 --]
end

if else语句

1
2
3
4
5
6
if(布尔表达式)
then
--[ 布尔表达式为 true 时执行该语句块 --]
else
--[ 布尔表达式为 false 时执行该语句块 --]
end

if else 嵌套

1
2
3
4
5
6
7
8
if( 布尔表达式 1)
then
--[ 布尔表达式 1 为 true 时执行该语句块 --]
if(布尔表达式 2)
then
--[ 布尔表达式 2 为 true 时执行该语句块 --]
end
end

函数

1
2
3
4
optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
function_body
return result_params_comma_separated
end
  • optional_function_scope: 该参数是可选的制定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local。

  • function_name: 指定函数名称。

  • argument1, argument2, argument3…, argumentn: 函数参数,多个参数以逗号隔开,函数也可以不带参数。

  • function_body: 函数体,函数中需要执行的代码语句块。

  • result_params_comma_separated: 函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。

Lua 运算符

算术运算符

^乘幂

关系运算符

  • == 等于,检测两个值是否相等,相等返回 true,否则返回 false
  • ~= 不等于,检测两个值是否相等,不相等返回 true,否则返回 false

逻辑运算符

  • and
  • or
  • not

其他运算符

  • ..,连接字符串
  • #,计算字符串长度

字符串

数组

数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。
array = {"Lua", "Tutorial"}

迭代器

迭代函数、状态常量、控制变量

泛型 for 迭代器

为什么交泛型迭代器

无状态的迭代器

Details
1
2
3
4
5
6
7
8
9
10
11
12
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end

for i,n in square,3,0
do
print(i,n)
end

输出

1
2
3
1    1
2 4
3 9

多状态的迭代器

很多情况下,迭代器需要保存多个状态信息而不是简单的状态常量和控制变量,最简单的方法是使用闭包,

Details
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
array = {"Google", "Runoob"}

function elementIterator (collection)
local index = 0
local count = #collection
-- 闭包函数
return function ()
index = index + 1
if index <= count
then
-- 返回迭代器的当前元素
return collection[index]
end
end
end

for element in elementIterator(array)
do
print(element)
end

输出

1
2
Google
Runoob

table(表)

  • Lua也是通过table来解决模块(module)、包(package)和对象(Object)的。 例如string.format表示使用”format”来索引table string。

模块与包

从 Lua 5.1 开始,Lua 加入了标准的模块管理机制
使用local的声明为程序块的局部变量,即表示一个私有函数,因此是不能从外部访问模块里的这个私有函数,必须通过模块里的公有函数来调用.

require 函数

  • require("<模块名>")
  • require "<模块名>"

C 包

与python类似

元表(Metatable)

用来自定义table的行为

协同程序(coroutine)

异常处理

pcall 和 xpcall、debug

垃圾回收

面对对象

lua 中的 function 可以用来表示方法。那么LUA中的类可以通过 table + function 模拟出来。
至于继承,可以通过 metetable 模拟出来(不推荐用,只模拟最基本的对象大部分时间够用了)。