泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。
型 for 迭代器提供了集合的 key/value 对
for k ,v in pairs(t) do
print(k,v)
end
--[[
for 变量列表 in 迭代函数,状态变量,控制变量 do
--循环体
end
--]]
-- 1、调用迭代函数,把状态变量和控制变量当做参数传递给迭代函数, 状态变量只会在第一次调用的时候赋值
--2、如果迭代函数的返回值为nil,退出for循环
--如果不是nil的话,把返回值赋值给变量列表,并执行循环体
function square(state,control)
if(control >= state)then
else
control = control +1
return control,control * control
end
end
--遍历
for i,j in square,9,0 do
print(i,j)
end
泛型for的执行过程
在lua中我们常常使用函数来描述迭代器,每次调用该函数,就返回集合的下一个元素,lua的迭代器包含以下两种类型
无状态的迭代器
function square(state,control)
if(control >= state)then
else
control = control +1
return control,control * control
end
end
--遍历
for i,j in square,9,0 do
print(i,j)
end
多状态的迭代器
array { "lua","Torotial"}
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
方法 | 用途 |
---|---|
table.concat (table [, sep [, start [, end]]]) | concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开。 |
table.insert (table, [pos,] value) | 在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾. |
table.maxn (table) | 指定table中所有正数key值中最大的key值. 如果不存在key值为正数的元素, 则返回0。(Lua5.2之后该方法已经不存在了)可以自己实现。 |
table.remove (table [, pos]) | 返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起。 |
table.sort (table [, comp]) | 对给定的table进行升序排序。 |
--初始化表
mytable = {}
--指定值
mytable[1] = "lua"
--移除引用
mytable = nil
--lua垃圾回收会自动释放内存
-- 简单的table
mytable = {}
print("mytable的类型是",type(mytable))
mytable[1]="Lua"
mytable["wow"] = "修改前"
print("mytable 的索引为1的元素是",mytable[1])
print("mytable 的索引为2的元素是",mytable["wow"])
--alternatetable 和mytable是指同一个table
alternatetable = mytable
print("alternatetable 的索引为1的元素是",alternatetable[1])
print("alternatetable 的索引为2的元素是",alternatetable["wow"])
alternatetable["wow"] = "修改后"
print("mytable索引为wow的元素是",mytable["wow"])
--释放变量
alternatetable = nil
print("alternatetable是",alternatetable)
--mytable任然可以访问
print(mytable["wow"])
mytable = nil
print(mytable)
用来加载模块。要加载一个模块,只需要简单地调用就可以了。
require("<模块名>")
require "<模块名>"
-- test_module.lua 文件
-- module 模块为上文提到到 module.lua
require("module")
print(module.constant)
module.func3()
通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index 键。如果__index包含一个表格,Lua会在表格中查找相应的键。
如果__index包含一个函数的话,Lua就会调用那个函数,table和键会作为参数传递给函数。
_index 元方法查看表中元素是否存在,如果不存在,返回结果为 nil;如果存在则由 index 返回结果。
mytabel = setmetable({key1 = "value"}{
__index = function (mytable,key)
return "metatablevalue"
else
return nil
end
end
}),
print (mytable.key1,mytable.key2)
-- mytable 表赋值为{key1 = "value"}
--mytable 设置了元表,方法为__index
--在mytable中查找key1,如果找到,返回该元素,找不到则继续
--在mytable中查找key2,乳沟找到则返回metatablevalue,找不到则继续
--判断元表中查看是否传入"key2"键的参数(mytable.key2已设置)如果传入“key2”参数返回metatablevalue否则返回mytable对应的键值
Lua查找表元素的规则如下
mymetatable = {}
mytable = setmetatable({key1 = "value1"},{__newindex = mymetatable})
print(mytable.key1)
mytable.newkey = "新值2"
print(mytable.newkey,mytable.newkey)
mytable.key1 = "新值1"
print(mytable.key1,mytable.key2)
--在对新索引键(newkey)赋值时(mytable.newkey = "新值2"),会调用元方法,而不进行赋值。而如果对已存在的索引键(key1),则会进行赋值,而不调用元方法 __newindex。
模式 | 描述 |
---|---|
__add | 对应的运算符 ‘+’. |
__sub | 对应的运算符 ‘-’. |
__mul | 对应的运算符 ‘*’. |
__div | 对应的运算符 ‘/’. |
__mod | 对应的运算符 ‘%’. |
__unm | 对应的运算符 ‘-’. |
__concat | 对应的运算符 ‘…’. |
__eq | 对应的运算符 ‘==’. |
__lt | 对应的运算符 ‘<’. |
__le | 对应的运算符 ‘<=’. |
方法 | 描述 |
---|---|
coroutine.create() | 创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用 |
coroutine.resume() | 重启coroutine,和create配合使用 |
coroutine.yield() | 挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果 |
coroutine.status() | 查看coroutine的状态 注:coroutine的状态有三种:dead,suspend,running,具体什么时候有这样的状态请参考下面的程序 |
coroutine.wrap() | 创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复 |
coroutine.running() | 返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号 |
co = coroutine.create(
function(i)
print(i)
end
)
coroutine.resume(co,1) --1
print(coroutine.status(co)) -- dead
print("------------")
co = coroutine.wrap(
function(i)
print(i)
end
)
co(1)
print("---------")
co2 = coroutine.create(
function()
for i = 1, 10 do
print(i)
if i == 3 then
print(coroutine.status(co2)) -- running
print(coroutine.running()) --therd.xxxxx
end
coroutine.yield()
end
end
)
coroutine.resume(co2) --1
coroutine.resume(co2) --2
coroutine.resume(co2) --2
print(coroutine.status(co2)) --suspended
print(coroutine.running())
print("-----------")
简单模式(simple model) 拥有一个当前输入文件和一个当前输出文件,并且提供针对 这些文件的相关操作
完全模式(complete model)使用外部的文件句柄来实现,它以一种面向对象的形式,将所有的文件操作定义为文件句柄的方法
mode的值有
模式 | 描述 |
---|---|
r | 以只读方式打开文件,该文件必须存在。 |
w | 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。 |
a | 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留) |
r+ | 以可读写方式打开文件,该文件必须存在。 |
w+ | 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。 |
a+ | 与a类似,但此文件可读可写 |
b | 二进制模式,如果文件是二进制文件,可以加上b |
+ | 号表示对文件既可以读也可以写 |
使用标准的 I/O 或使用一个当前输入文件和一个当前输出文件。
--以只读方式打开文件
file = io.open("test.lua","r")
--设置默认输入文件为test.lua
io.input(file)
--输出文件第一行
print(io.read())
--关闭打开的文件
io.close(file)
--以附加的方式打开只写文件
file = io.open("test.lua","a")
--设置默认输出文件为test.lua
io.output(file)
--在文件最后一行添加lua注释
io.write("-- test.lua文件末尾注释")
--关闭打开的文件
io.close(file)
在以上实例中我们使用了 io.“x” 方法,其中 io.read() 中我们没有带参数,参数可以是下表中的一个:
模式 | 描述 |
---|---|
“*n” | 读取一个数字并返回它。例:file.read("*n") |
“*a” | 从当前位置读取整个文件。例:file.read("*a") |
“*l”(默认) | 读取下一行,在文件尾 (EOF) 处返回 nil。例:file.read("*l") |
number | 返回一个指定字符个数的字符串,或在 EOF 时返回 nil。例:file.read(5) |
其他的 io 方法有:
通常我们需要在同一时间处理多个文件。我们需要使用 file:function_name 来代替 io.function_name 方法。
file:seek(optional whence, optional offset): 设置和获取当前文件位置,成功则返回最终的文件位置(按字节),失败则返回nil加错误信息。参数 whence 值可以是:
不带参数file:seek()则返回当前位置,file:seek(“set”)则定位到文件头,file:seek(“end”)则定位到文件尾并返回文件大小
file:flush(): 向文件写入缓冲中的所有数据
io.lines(optional file name): 打开指定的文件filename为读模式并返回一个迭代函数,每次调用将获得文件中的一行内容,当到文件尾时,将返回nil,并自动关闭文件。
error (message [, level])
函数库主要函数
debug(): | 进入一个用户交互模式,运行用户输入的每个字符串。 使用简单的命令以及其它调试设置,用户可以检阅全局变量和局部变量, 改变变量的值,计算一些表达式,等等。 输入一行仅包含 cont 的字符串将结束这个函数, 这样调用者就可以继续向下运行。 |
---|---|
getfenv(object): | 返回对象的环境变量。 |
gethook(optional thread): | 返回三个表示线程钩子设置的值: 当前钩子函数,当前钩子掩码,当前钩子计数 |
getinfo ([thread,] f [, what]): | 返回关于一个函数信息的表。 你可以直接提供该函数, 也可以用一个数字 f 表示该函数。 数字 f 表示运行在指定线程的调用栈对应层次上的函数: 0 层表示当前函数(getinfo 自身); 1 层表示调用 getinfo 的函数 (除非是尾调用,这种情况不计入栈);等等。 如果 f 是一个比活动函数数量还大的数字, getinfo 返回 nil。 |
debug.getlocal ([thread,] f, local): | 此函数返回在栈的 f 层处函数的索引为 local 的局部变量 的名字和值。 这个函数不仅用于访问显式定义的局部变量,也包括形参、临时变量等。 |
getmetatable(value): | 把给定索引指向的值的元表压入堆栈。如果索引无效,或是这个值没有元表,函数将返回 0 并且不会向栈上压任何东西。 |
getregistry(): | 返回注册表表,这是一个预定义出来的表, 可以用来保存任何 C 代码想保存的 Lua 值。 |
getupvalue (f, up) | 此函数返回函数 f 的第 up 个上值的名字和值。 如果该函数没有那个上值,返回 nil 。 以 ‘(’ (开括号)打头的变量名表示没有名字的变量 (去除了调试信息的代码块)。 |
sethook ([thread,] hook, mask [, count]): | 将一个函数作为钩子函数设入。 字符串 mask 以及数字 count 决定了钩子将在何时调用。 掩码是由下列字符组合成的字符串,每个字符有其含义:‘c’: 每当 Lua 调用一个函数时,调用钩子; ‘r’: 每当 Lua 从一个函数内返回时,调用钩子; ‘l’: 每当 Lua 进入新的一行时,调用钩子。 |
setlocal ([thread,] level, local, value): | 这个函数将 value 赋给 栈上第 level 层函数的第 local 个局部变量。 如果没有那个变量,函数返回 nil 。 如果 level 越界,抛出一个错误。 |
setmetatable (value, table): | 将 value 的元表设为 table (可以是 nil)。 返回 value。 |
setupvalue (f, up, value): | 这个函数将 value 设为函数 f 的第 up 个上值。 如果函数没有那个上值,返回 nil 否则,返回该上值的名字。 |
traceback ([thread,][message [, level]]): | 如果 message 有,且不是字符串或 nil, 函数不做任何处理直接返回 message。 否则,它返回调用栈的栈回溯信息。 字符串可选项 message 被添加在栈回溯信息的开头。 数字可选项 level 指明从栈的哪一层开始回溯 (默认为 1 ,即调用 traceback 的那里)。 |
创建对象是为类的实例分配内存的过程。每个类都有属于自己的内存并共享公共数据。
r = Rectangle:new(nil,10,20)
我们可以使用点号(.)来访问类的属性:
print(r.length)
我们可以使用冒号 : 来访问类的成员函数:
r:printArea()