lua学习笔记

lua也是一门强大的语言,现将学习笔记简要记录如下:

  1. 变量

lua中的变量默认总是全局的,除非用local声明它。变量没有类型,值才有类型。一个变量在未使用时它的值为nil,同理可将一个已经使用完毕的变量赋值为nil,就删除了这个变量。

  1. 类型

lua中总共有8种类型,如下:










































类型 描述
nil 该类型的值只有一个,即nil
boolean 布尔类型,有true和false两种值
number 数字类型,所有整形和实数都用number表示
string 字符串
function 函数类型,和C不同,lua中函数也是一种类型,意味着可以将函数赋值给变量
userdata 用户自定义类型,对等于C中struct
thread 线程类型
table 表,也正是lua的强大之处,集成了map,数组等数据结构

其中只有nil和false表示假,其他值均表示真,包括0和空字符串。

字符串可以用单引号、双引号和”[[“,”]]”表示。“..”两个点用来连接两个字符串。”#“用来求字符串长度。当该出现字符串的地方而出现数字时,lua会将数字转换为字符串。

table支持[]操作符。

  1. lua和go一样都支持多赋值和多值返回,不再赘述。如果复制好两边变量个数不相等时,若左边多,则将右边的依次赋值给左边的变量,其余的为nil。若右边多,多出来的被抛弃。

  2. 循环

lua支持3种循环方式:

1.  while
1
2
3
4
while(condition)
do
--something;
end
  1. for
1
2
3
for var=exp1,exp2,exp3 do
--something
end

表示变量var从exp1变化到exp2,每次步距为exp3。如果不写exp3,默认为1.和C不一样的是,这三个表达式只在循环开始前求值一次,之后不再计算。

for的另一种写法为(设a为一个数组):

1
2
3
for index,val in ipairs(a) do
print(val)
end

这是for循环的泛型写法,作用是打印数组的所有值。

  1. repeat…until

类似于C中的do…while循环,写法上也一致:

1
2
3
repeat
--something
until(condition)
  1. 条件语句

条件判断语句如下:

1
2
3
4
5
6
7
8
9
if (condition)
then
--something
elif
then
--other
else
--lastthing
end

上面说过了,在lua中,只有false和nil被认定为假,其他的均为真。重说三!

  1. 函数

lua中函数的写法如下:

1
2
3
f = function (arg1,arg2...)
--something
end

不过这种写法不符合我们的习惯,所以lua提供了语法糖的函数形式:

1
2
3
function f(arg1,arg2...)
--something
end

说明几点:

  • lua中函数也是值,因此可以赋值给变量。这种语法使得lua支持闭包,也可以将函数作为另一个函数的参数。

  • 和Go一样,函数支持多返回值。

  1. 运算符
  • ~=表示不等于

  • 逻辑运算符分别为and,or,not

  • ..用于连接两个字符串

  • #用于求字符串的长度

  • 其他运算符和C一致。

  1. 数组

在lua中,数组是用表来表示的,可以用[]来索引数组元素,如下:

1
2
3
4
array={"one","two","three","four"}
for index =1,4,1 do
print (array[index])
end

如你所见,数组的默认下标是从1开始的,不过我们可以修改。

表是lua提供的功能强大的数据结构,可以用来存储任何key-value值对。

t={}即可创建一个空表,t["first"]=1即可向里面添加元素。

此外,lua库里面有许多表操作函数,在此不写了,感兴趣的读者可以搜索相关资料。

  1. 模块与包

lua中的模块是有变量、函数等已知元素组成的table,因此创建一个模块很简单,就是创建一个table,然后把最要导出的函数、常量放入其中,最后返回这个table就行了。对我来说,从思维上认识到这一点的转变很重要。举个例子:

1
2
3
4
5
6
module={}
module.const1="hello world"
function module.fun()
return "hello world"
end
return module

使用require函数来加载一个模块:require ("模块名")或者require "模块名"

  1. 元表,暂时没写

  2. 协程

全称协同程序,与线程类似,都拥有独立的堆栈,指令指针和共享全局变量等。但协程是在用户态实现的,而线程是由操作系统在系统态实现的,也就是说在多核CPU上多个线程可以并行执行,而协程只能是并发的(请自行查找并发和并行的区别)。可以说协程就是加上了同步锁的线程。

用法:

|方法|描述|

|:—:|:—–:|

|coroutine.create()|创建一个协程并返回它,参数是一个函数|

|coroutine.resume()|重启coroutine|

|coroutine.yield()|挂起coroutine|

|coroutine。status()|查看coroutine的状态,有三种状态:dead,sudpend,running|

|coroutine.wrap()|返回一个coroutine函数,当调用该函数时就直接进入coroutine|

|coroutine.running()|返回当前正在运行的coroutine的线程id|

  1. 文件操作

以下是打开文件和关闭文件的操作:

1
2
file = io.open(filename,mode)
io.close(file)

lua的文件操作分两种:简单模式和完全模式

简单模式:当程序中只打开一个文件时,使用简单模式更方便,打开文件后,设置默认输入输出文件,然后直接调用库函数就OK,比如:

1
2
io.input("test.txt") --设置默认输入文件为test.txt
print(io.read()) --打印文件第一行

完全模式:可以打开多个文件,使用文件句柄来访问即可:

1
2
3
file=io.open("test.txt",a)
file:write("hello world")
file:close()