lua基础知识整理

lua入门
    参考资料:https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/file.html


一.数据类型
可以通过type()函数来确实变量的类型
eg:
print(type("hello world")) 
print(type(type))         
print(type(true))          
print(type(360.0))         
print(type(nil))           
1.nil(空)
nil 是一种类型,Lua 将 nil 用于表示“无效值”。一个变量在第一次赋值前的默认值是 nil,将 nil 赋予给一个全局变量就等同于删除它。
eg:
local a
print a   


a = 100
print(a)
2.boolean(布尔)
布尔类型,可选值 true/false;Lua 中 nil 和 false 为“假”,其它所有值均为“真”。比如 0 和空字符串就是“真”。
eg:
local a = true
local b = 0
local c = nil
local d = false
if a then
print("a")
else
print("not a")
end


if b then
print("b")
else
print("not b")
end


if c then
print("c")
else
print("not c")
end


if d then
print("d")
else
print("not d")
end
3.number(数字)
Number 类型用于表示实数,和 C/C++ 里面的 double 类型很类似。可以使用数学函数 math.floor(向下取整)和 math.ceil(向上取整)进行取整操作。
eg: 
local order = 3.0
local score = 98.5
local id = 444
print(math.floor(order))
print(math.ceil(score))
print(id)
4.string(字符串)
在Lua 中有三种方式表示字符串:a.使用一对匹配的单引号;b.使用一对匹配的双引号;c.使用一种长括号(即[[ ]])括起来的方式定义。Lua 的字符串是不可改变的值,不能像在 c 语言中那样直接修改字符串的某个字符,而是根据修改要求来创建一个新的字符串。Lua 也不能通过下标来访问字符串的某个字符。
Lua 字符串一般都会经历一个“内化”(intern)的过程,即两个完全一样的 Lua 字符串在 Lua 虚拟机中只会存储一份。每一个 Lua 字符串在创建时都会插入到 Lua 虚拟机内部的一个全局的哈希表中。 这意味着:
a.创建相同的 Lua 字符串并不会引入新的动态内存分配操作,所以相对便宜(但仍有全局哈希表查询的开销),
b.内容相同的 Lua 字符串不会占用多份存储空间,
c.已经创建好的 Lua 字符串之间进行相等性比较时是 O(1) 时间度的开销,而不是通常见到的 O(n).


eg:
local str1 = 'hello world'
local str2 = "hello world"
local str3 = [["hello\nworld"]]
local str4 = [=["hello\nworld"]=]
print(str1)
print(str2)
print(str3)
print(str4)
5.table(表)
Table 类型实现了一种抽象的“关联数组”。“关联数组” 是一种具有特殊索引方式的数组,索引通常是字符串(string)或者 number 类型,但也可以是除 nil 以外的任意类型的值。在内部实现上,table 通常实现为一个哈希表、一个数组、或者两者的混合。具体的实现为何种形式,动态依赖于具体的 table 的键分布特点。


eg:
local corp = {


web = "www.baidu.com",   --索引为字符串,值为字符串
telephone = "12345",--索引为字符串,值为字符串
staff = {"a","b"},--索引为字符串,值为表
10086, --索引为数字,值为数字
10087, --索引为数字,值为数字
[10] = 10088, --索引为数字,值为数字
["city"] = "Beijing"--索引为字符串,值为字符串
}
print(corp.web)
print(corp["telephone"])
print(corp[2])
print(corp["city"])
print(corp.staff[1])
6.function(函数)
在 Lua 中,函数 也是一种数据类型,函数可以存储在变量中,可以通过参数传递给其他函数,还可以作为其他函数的返回值。


eg:
local function foo()
print("in the function")
local x = 1
local y = 2
return x + y
end
local a = foo --把函数赋给变量
print (a())


二.表达式
1.算术运算符
eg:
print(1+2)          --加法
print(3-2) --减法
print(5/10) --除法
print(5.0/10) --除法
print(2^10) --指数
print(4%3) --取模
print(4*3) --乘法


2.关系运算符
eg:
print(1>2)        --大于
print(3>=2)  --大于等于
print(4<5)  --小于
print(4<=3)  --小于等于
print(4 == 5)  --等于
print(4 ~= 5)  --不等于


3.逻辑运算符
eg:
local a = nil
local b = 0 
local c = 100
local d = false
print(a and c)  --逻辑与
print(b and c)--逻辑与
print(d and b)--逻辑与
print(d and c)--逻辑与
print(a or c) --逻辑或
print(d or d) --逻辑或
print(not a) --逻辑非
print(not d) --逻辑非
print(not c) --逻辑非


4.字符串连接
在 Lua 中连接两个字符串,可以使用操作符“..”(两个点)。如果其任意一个操作数是数字的话,Lua 会将这个数字转换成字符串。注意,连接操作符只会创建一个新字符串,而不会改变原操作数。
由于 Lua 字符串本质上是只读的,因此字符串连接运算符几乎总会创建一个新的(更大的)字符串。这意味着如果有很多这样的连接操作(比如在循环中使用 .. 来拼接最终结果),则性能损耗会非常大。在这种情况下,推荐使用 table 和 table.concat() 来进行很多字符串的拼接.
eg:
print("hello" .. "world")
print(0 .. 1)


三.控制结构
1.if-else
与 C 语言的不同之处是 elseif 是连在一起的,若不 else 与 if 写成 "else if" 则相当于在 else 里嵌套
eg:
x = 10
if x > 0 then
print("x is a positive number")
end


if x > 0 then
print("x is a positive number")
else
print("x is a non-positive number")
end


if x == 10 then
print("x is 10")
elseif x > 0 then
print("x is a positive number")
else
print("x is a non-positive number")
end


2.while
while 型控制结构语法如下,当表达式值为假(即false或nil)时结束循环。也可以使用 break 语言提前跳出循环。没有提供 do-while 型的控制结构,但是提供了功能相当的 repeat。
while  表达式  do
--body
end
eg:
x = 1
sum = 0
while x <10 do
sum = sum + x
if  sum > 10 then
break
end
x = x + 1
end
print(sum)
print(x)


3.repeat
Lua 中的 repeat 控制结构类似于其他语言(如:C++语言)中的 do-while,但是控制方式是刚好相反的。简单点说,执行 repeat 循环体后,直到 until 的条件为真时才结束,而其他语言(如:C++语言)的 do-while 则是当条件为假时就结束循环。
repeat 也可以在使用 break 退出。
eg:
x = 10
repeat
x = x +1
print(x)
until x >= 20


    4.for
    for 语句有两种形式:数字 for(numeric for)和范型 for(generic for
    a.数字型
    for var = begin, finish, step do
   --body
end
eg:
for i = 1, 5 do
 print(i)
end
for 需要关注以下几点: 
1.var 从 begin 变化到 finish,每次变化都以 step 作为步长递增 var 
2.begin、 finish、 step 三个表达式只会在循环开始时执行一次 
3.第三个表达式 step 是可选的, 默认为 1 
4.控制变量 var 的作用域仅在 for 循环内,需要在外面控制,则需将值赋给一个新的变量 
5.循环过程中不要改变控制变量的值,那样会带来不可预知的影响
b.泛型
泛型 for 循环通过一个迭代器(iterator)函数来遍历所有值
eg:
local a = {"a", "b", "c", "d"}
for i, v in ipairs(a) do
 print("index:", i, " value:", v)
end


5.break
语句 break 用来终止 while、repeat 和 for 三种循环的执行,并跳出当前循环体, 继续执行当前循环之后的语句。
eg:
sum = 0
i = 1
while true do
   sum = sum + i
   if sum > 100 then
       break
   end
   i = i + 1
end
print("The result is " .. i)


    6.return
    return 主要用于从函数中返回结果,或者用于简单的结束一个函数的执行。 一旦执行了 return 语句,该语句之后的所有语句都不会再执行。若要写在函数中间,则只能写在一个显式的语句块内.
    为了调试方便,我们可以想在某个函数的中间提前 return,以进行控制流的短路。此时我们可以将 return 放在一个 do ... end 代码块中.
    eg:
    local function add(x, y)
   return x + y
   --print("add: I will return the result " .. (x + y))
   --因为前面有个return,若不注释该语句,则会报错
end


local function is_positive(x)
   if x > 0 then
       return x .. " is positive"
   else
       return x .. " is non-positive"
   end


   --由于return只出现在前面显式的语句块,所以此语句不注释也不会报错
   --,但是不会被执行,此处不会产生输出
   print("function end!")
end


local function foo()
   print("before")
   do return end
   print("after")  -- 这一行语句永远不会执行到
end


四.函数
函数是一种对语句和表达式进行抽象的主要机制。函数既可以完成某项特定的任务,也可以只做一些计算并返回结果。在第一种情况中,一句函数调用被视为一条语句;而在第二种情况中,则将其视为一句表达式。
由于函数定义本质上就是变量赋值,而变量的定义总是应放置在变量使用之前,所以函数的定义也需要放置在函数调用之前。
a.函数定义
function function_name (arc)  -- arc 表示参数列表,函数的参数列表可以为空
  -- body
end
由于全局变量一般会污染全局名字空间,同时也有性能损耗(即查询全局环境表的开销),因此我们应当尽量使用“局部函数”,其记法是类似的,只是开头加上 local 修饰符.
local function function_name (arc)
 -- body
end
b.函数的参数
在调用函数的时候,若形参个数和实参个数不同时,Lua 会自动调整实参个数。调整规则:若实参个数大于形参个数,从左向右,多余的实参被忽略;若实参个数小于形参个数,从左向右,没有被实参初始化的形参会被初始化为 nil。
1.按值传递
eg:
local function swap(a, b) --定义函数swap,函数内部进行交换两个变量的值
  local temp = a
  a = b
  b = temp
  print(a, b)
end


2.变长参数
Lua 还支持变长参数。若形参为 ... ,表示该函数可以接收不同长度的参数。访问参数的时候也要使用 ... 。
eg:
local function func( ... )                -- 形参为 ... ,表示函数采用变长参数


  local temp = {...}                     -- 访问的时候也要使用 ...
  local ans = table.concat(temp, " ")    -- 使用 table.concat 库函数对数
                                         -- 组内容使用 " " 拼接成字符串。
  print(ans)
end


3.具名参数
Lua 还支持通过名称来指定实参,这时候要把所有的实参组织到一个 table 中,并将这个 table 作为唯一的实参传给函数。
eg:
local function change(arg) -- change 函数,改变长方形的长和宽,使其各增长一倍
 arg.width = arg.width * 2
 arg.height = arg.height * 2
 return arg
end


local rectangle = { width = 20, height = 15 }
print("before change:", "width  =", rectangle.width,
                       "height =", rectangle.height)


4.按引用传递
当函数参数是 table 类型时,传递进来的是 实际参数的引用,此时在函数内部对该 table 所做的修改,会直接对调用者所传递的实际参数生效,而无需自己返回结果和让调用者进行赋值。
eg:
local function change(arg) -- change 函数,改变长方形的长和宽,使其各增长一倍
 arg.width = arg.width * 2
 arg.height = arg.height * 2
 return arg
end


local rectangle = { width = 20, height = 15 }
print("before change:", "width  =", rectangle.width,
                       "height =", rectangle.height)
c.函数返回值
Lua 具有一项与众不同的特性,允许函数返回多个值。当函数返回值的个数和接收返回值的变量的个数不一致时,Lua 也会自动调整参数个数。调整规则: 若返回值个数大于接收变量的个数,多余的返回值会被忽略掉; 若返回值个数小于参数个数,从左向右,没有被返回值初始化的变量会被初始化为 nil。
eg:
local function swap(a, b)   -- 定义函数 swap,实现两个变量交换值
  return b, a              -- 按相反顺序返回变量的值
end

local x = 1
local y = 20
x, y = swap(x, y)           -- 调用 swap 函数
print(x, y)    


local x, y, z = swap(x, y), 2   -- swap 函数的位置不在最后,此时只返回b的值
print(x, y, z)  


print((swap(x, y)), 2)   --确保只取函数返回值的第一个值,可以使用括号运算符
print(2, (swap(x, y)))   --确保只取函数返回值的第一个值,可以使用括号运算符


五.模块
一个 Lua 模块的数据结构是用一个 Lua 值(通常是一个 Lua 表或者 Lua 函数)。一个 Lua 模块代码就是一个会返回这个 Lua 值的代码块。 可以使用内建函数 require() 来加载和缓存模块。简单的说,一个代码模块就是一个程序库,可以通过 require 来加载。模块加载后的结果通过是一个 Lua table,这个表就像是一个命名空间,其内容就是模块中导出的所有东西,比如函数和变量。require 函数会返回 Lua 模块加载后的结果,即用于表示该 Lua 模块的 Lua 值。
eg:
--把下面的代码保存在文件 my.lua 中
local foo={}


local function getname()
   return "Lucy"
end


function foo.greeting()
   print("hello " .. getname())
end


return foo


--把下面代码保存在文件 main.lua 中,然后执行 main.lua,调用上述模块。
local fp = require("my")
fp.greeting()


六.String 库
Lua 字符串内部用来标识各个组成字节的下标是从 1 开始的,这不同于像 C 和 Perl 这样的编程语言。其用法为:ans = string.upper(s) ,也能写成 ans = s:upper()。为了避免与之前版本不兼容,此处使用前者。


1.string.byte(s [, i [, j ]]) --返回字符 s[i]、s[i + 1]、s[i + 2]、······、s[j] 所对应的 ASCII 码
eg:
print(string.byte("abc", 1, 3))
print(string.byte("abc", 3)) -- 缺少第三个参数,第三个参数默认与第二个相同,此时为 3
print(string.byte("abc"))    -- 缺少第二个和第三个参数,此时这两个参数都默认为 1
2.string.char (...) --接收 0 个或更多的整数(整数范围 :0~255),返回这些整数所对应的 ASCII 码字符组成的字符串
eg:
print(string.char(96, 97, 98))
print(string.char())        -- 参数为空,默认是一个0,可以用string.byte(string.char())测试一下
print(string.char(65, 66))
3.string.upper(s)  --接收一个字符串s,返回一个把所有小写字母变成大写字母的字符串
eg:
print(string.upper("Hello Lua")) 
4.string.lower(s) --接收一个字符串s,返回一个把所有大写字母变成小写字母的字符串。
eg:
print(string.lower("Hello Lua"))  --接收一个字符串s,返回一个把所有大写字母变成小写字母的字符串。
5.string.len(s)  --接收一个字符串,返回它的长度
eg:
print(string.len("hello lua"))
6.string.find(s, p [, init [, plain]]) --在 s 字符串中第一次匹配 p 字符串。若匹配成功,则返回 p 字符串在 s 字符串中出现的开始位置和结束位置;若匹配失败,则返回 nil。 第三个参数 init 默认为 1,并且可以为负整数,当 init 为负数时,表示从 s 字符串的 string.len(s) + init 索引处开始向后匹配字符串 p 。 第四个参数默认为 false,当其为 true 时,只会把 p 看成一个字符串对待
eg:
local find = string.find
print(find("abc cba", "ab"))
print(find("abc cba", "ab", 2))     -- 从索引为2的位置开始匹配字符串:ab
print(find("abc cba", "ba", -1))    -- 从索引为7的位置开始匹配字符串:ba
print(find("abc cba", "ba", -3))    -- 从索引为6的位置开始匹配字符串:ba
print(find("abc cba", "(%a+)", 1))  -- 从索引为1处匹配最长连续且只含字母的字符串
print(find("abc cba", "(%a+)", 1, true)) --从索引为1的位置开始匹配字符串:(%a+)
7.string.format(formatstring, ...) --按照格式化参数 formatstring,返回后面 ... 内容的格式化版本
eg:
print(string.format("%.4f", 3.1415926))     -- 保留4位小数
print(string.format("%d %x %o", 31, 31, 31))-- 十进制数31转换成不同进制
d = 29; m = 7; y = 2015                     -- 一行包含几个语句,用;分开
print(string.format("%s %02d/%02d/%d", "today is:", d, m, y))
8.string.match(s, p [, init]) --在字符串 s 中匹配(模式)字符串 p,若匹配成功,则返回目标字符串中与模式匹配的子串;否则返回 nil。第三个参数 init 默认为 1,并且可以为负整数,当 init 为负数时,表示从 s 字符串的 string.len(s) + init 索引处开始向后匹配字符串 p
eg:
print(string.match("hello lua", "lua"))
print(string.match("lua lua", "lua", 2))  --匹配后面那个lua
print(string.match("lua lua", "hello"))
print(string.match("today is 27/7/2015", "%d+/%d+/%d+"))
9.string.gmatch(s, p) --返回一个迭代器函数,通过这个迭代器函数可以遍历到在字符串s中出现模式串p的所有地方
eg:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%a+)=(%a+)") do  --匹配两个最长连续且只含字母的
   t[k] = v                                    --字符串,它们之间用等号连接
end
for k, v in pairs(t) do
print (k,v)
end
    10.string.sub(s, i [, j]) --返回字符串 s 中,索引 i 到索引 j 之间的子字符串。当 j 缺省时,默认为 -1,也就是字符串 s 的最后位置。 i 可以为负数。当索引 i 在字符串 s 的位置在索引 j 的后面时,将返回一个空字符串。
    eg:
    print(string.sub("Hello Lua", 4, 7))
print(string.sub("Hello Lua", 2))
print(string.sub("Hello Lua", 2, 1))    --看到返回什么了吗
print(string.sub("Hello Lua", -3, -1))
11.string.gsub(s, p, r [, n]) --将目标字符串 s 中所有的子串 p 替换成字符串 r。可选参数 n,表示限制替换次数。返回值有两个,第一个是被替换后的字符串,第二个是替换了多少次
eg:
print(string.gsub("Lua Lua Lua", "Lua", "hello"))
print(string.gsub("Lua Lua Lua", "Lua", "hello", 2))
    12.string.reverse (s) --接收一个字符串s,返回这个字符串的反转
    eg:
    print(string.reverse("Hello Lua"))


七.table 库
table 库是由一些辅助函数构成的,这些函数将 table 作为数组来操作。在 Lua 中,数组下标从 1 开始计数。在初始化一个数组的时候,若不显式地用键值对方式赋值,则会默认用数字作为下标,从 1 开始。由于在 Lua 内部实际采用哈希表和数组分别保存键值对、普通值,所以不推荐混合使用这两种赋值方式。
1.table.getn --获取长度
eg:
local tblTest1 = { 1, a = 2, 3 }
print("Test1 " .. table.getn(tblTest1))


local tblTest2 = { 1, nil }
print("Test2 " .. table.getn(tblTest2))


local tblTest3 = { 1, nil, 2 }
print("Test3 " .. table.getn(tblTest3))


local tblTest4 = { 1, nil, 2, nil }
print("Test4 " .. table.getn(tblTest4))
    2.table.concat (table [, sep [, i [, j ] ] ]) --对于元素是 string 或者 number 类型的表 table,返回 table[i]..sep..table[i+1] ··· sep..table[j] 连接成的字符串。填充字符串 sep 默认为空白字符串。起始索引位置 i 默认为 1,结束索引位置 j 默认是 table 的长度。如果 i 大于 j,返回一个空字符串
    eg:
    local a = {1, 3, 5, "hello" }
print(table.concat(a))             
print(table.concat(a, "|"))        
print(table.concat(a, " ", 4, 2))  
print(table.concat(a, " ", 2, 4))
3.table.insert (table, [pos ,] value) --在(数组型)表 table 的 pos 索引位置插入 value,其它元素向后移动到空的地方。pos 的默认值是表的长度加一,即默认是插在表的最后
eg:
local a = {1, 8}             --a[1] = 1,a[2] = 8
table.insert(a, 1, 3)   --在表索引为1处插入3
print(a[1], a[2], a[3])
table.insert(a, 10)    --在表的最后插入10
print(a[1], a[2], a[3], a[4])
4.table.maxn (table) --返回(数组型)表 table 的最大索引编号;如果此表没有正的索引编号,返回 0
eg:
local a = {}
a[-1] = 10
print(table.maxn(a))
a[5] = 10
print(table.maxn(a))
5.table.remove (table [, pos]) --在表 table 中删除索引为 pos(pos 只能是 number 型)的元素,并返回这个被删除的元素,它后面所有元素的索引值都会减一。pos 的默认值是表的长度,即默认是删除表的最后一个元素
eg:
local a = { 1, 2, 3, 4}
print(table.remove(a, 1)) --删除速索引为1的元素
print(a[1], a[2], a[3], a[4])


print(table.remove(a))   --删除最后一个元素
print(a[1], a[2], a[3], a[4])
6.table.sort (table [, comp]) --按照给定的比较函数 comp 给表 table 排序,也就是从 table[1] 到 table[n] ,这里 n 表示 table 的长度。 比较函数有两个参数,如果希望第一个参数排在第二个的前面,就应该返回 true,否则返回 false。 如果比较函数 comp 没有给出,默认从小到大排序
eg:
local function compare(x, y) --从大到小排序
  return x > y         --如果第一个参数大于第二个就返回true,否则返回false
end


local a = { 1, 7, 3, 4, 25}
table.sort(a)           --默认从小到大排序
print(a[1], a[2], a[3], a[4], a[5])
table.sort(a, compare) --使用比较函数进行排序
print(a[1], a[2], a[3], a[4], a[5])


八.数学库
eg:
print(math.pi)         --圆周率  
print(math.rad(180))     --角度转换成弧度
print(math.deg(math.pi)) --弧度转换成角度


print(math.sin(1))       
print(math.cos(math.pi)) 
print(math.tan(math.pi / 4))  


print(math.atan(1))      
print(math.asin(0))      


print(math.max(-1, 2, 0, 3.6, 9.1))     
print(math.min(-1, 2, 0, 3.6, 9.1))     


print(math.fmod(10.1, 3))   
print(math.sqrt(360))     


print(math.exp(1))         
print(math.log(10))       
print(math.log10(10))    


print(math.floor(3.1415))
print(math.ceil(7.998))    


九.文件操作
Lua I/O 库提供两种不同的方式处理文件:隐式文件描述,显式文件描述。任何文件的操作,都将阻塞其他并行执行的请求。
1.隐式文件描述
设置一个默认的输入或输出文件,然后在这个文件上进行所有的输入或输出操作。所有的操作函数由 io 表提供。
eg:
file = io.input("test1.txt")    -- 使用 io.input() 函数打开文件


repeat
   line = io.read()            -- 逐行读取内容,文件结束时返回nil
   if nil == line then
       break
   end
   print(line)
until (false)


io.close(file)                  -- 关闭文件


2.显式文件描述
使用 file:XXX() 函数方式进行操作,其中 file 为 io.open() 返回的文件句柄。
eg:
file = io.open("test2.txt", "r")    -- 使用 io.open() 函数,以只读模式打开文件


for line in file:lines() do         -- 使用 file:lines() 函数逐行读取文件
  print(line)
end


file:close()


十.基本函数
1.assert(arg [, message]) -- arg 为false,程序中断; 为true时,正常执行
2.ipairs(table) --迭代数组元素{1,2,3,4}
3.pairs(table) --迭代table元素{x1=1, x2=2, x3=3, x4=4}


lua高阶
一.元表
在lua中,只能设置table的元表。要设置其它类型的元表,必须通过C代码来完成.
mt = {}
mt.__add = function(a, b){
// todo
}
mt.__sub = function(a, b){
// todo
}
mt.__sub = function(a, b){
// todo
}
mt.__mul = function(a, b){
// todo
}
mt.__div = function(a, b){
// todo
}
mt.__pow = function(a, b){
// todo
}
mt.__concat = function(a, b){
// todo
}
mt.__eq = function(a, b){
// todo
}
mt.__lt = function(a, b){
// todo
}
mt.__le = function(a, b){
// todo
}
mt.__sub = function(a, b){
// todo
}
a = {1,2,3}
b = {4,5,6}
setmetatable(a, mt)
setmetatable(b, mt)
a + b   -- 运行元表中的__add方法
a - b   -- 运行元表中的__sub方法
 
二.面向对象编程
在Lua中,可以通过使用函数和表来实现面向对象。将函数和相关的数据放置于同一个表中就形成了一个对象。
local Person = {}


function Person:new(name, age)
   return setmetatable({name = name, age = age}, {__index = self})
end


function Person:info()
 print(self.name, self.age)
end


function Person:sayname()
   print('name:', self.name)
end


local p1 = Person:new('zhangsan', 12)
p1:info()
p1:sayname()


local Student = {}


function Student:new(name, age, class)
   setmetatable(self, {__index = Person:new(name, age)}) -- 继承父类
   return setmetatable({ class = class}, {__index = self})
end


-- 方法重写
function Student:info()
   print(self.name, self.age, self.class)
end


local p2 = Student:new('lisi', 6, 'w')
p2:info()
p1:sayname() --调用父类方法


三.协程
function test1()
while true do
local res, v1, v2 = coroutine.resume(co1, 1, 3)
print(v1, v2)
end
end
--创建协程
co1 = coroutine.create(test1)
function test2()
while true do
local res, v1, v2 = coroutine.yield(100, 300ssssssssss)
print(v1, v2)
end
end
--创建协程
co2 = coroutine.create(test2)
--查看状态
coroutine.status(co1)
--调用
coroutine.resume(co1)


四 全局变量(_G)
   a= b
   for k, v in pairs(_G) do
    print(k, v)  -- 是可以看到有a的,这是全局变量
   end


五.require执行流程
首先,在package.loaded查找modulname
其次,在package.preload查找modelname,如果存在就作为loader,调用loader(L)
然后,在package.path查找lua文件
最后,在package.cpath查找c库,并调用相关的接口


六.module
   --mathlib.lua 文件
   module(...)
   function add(a, b)
       return a +b 
   end
   -- test.lua 
   local lib = require('mathlib')
   print(mathlib.add(1,2))  -- 第一种调用方式
   print(lib.add(1,2)) -- 第二种调用方式








































lua中文教程,原名:programming in lua 目录 版权声明..............i 译序..i 目录iii 第一篇语言.......1 第0章序言.......1 0.1 序言..........1 0.2 Lua的使用者................2 0.3 Lua的相关资源............3 0.4 本书的体例.................3 0.5 关于本书...3 0.6 感谢..........4 第1章起点.......5 1.1 Chunks.......5 1.2 全局变量...7 1.3 词法约定...7 1.4 命令行方式.................7 第2章类型和值9 2.1 Nil..............9 2.2 Booleans....9 2.3 Numbers...10 2.4 Strings......10 2.5 Functions.12 2.6 Userdata and Threads.12 第3章表达式..13 3.1 算术运算符...............13 3.2 关系运算符...............13 3.3 逻辑运算符...............13 3.4 连接运算符...............14 3.5 优先级.....15 3.6表的构造..15 第4章基本语法................18 4.1 赋值语句.18 4.2 局部变量与代码块(block)......19 4.3 控制结构语句...........20 Programming in Lua iv Copyright ® 2005, Translation Team, www.luachina.net 4.4 break和return语句......23 第5章函数......24 5.1 返回多个结果值.......25 5.2可变参数..27 5.3 命名参数.28 第6章再论函数................30 6.1 闭包........32 6.2 非全局函数...............34 6.3 正确的尾调用(Proper Tail Calls)...36 第7章迭代器与泛型for....40 7.1 迭代器与闭包...........40 7.2 范性for的语义...........42 7.3 无状态的迭代器.......43 7.4 多状态的迭代器.......44 7.5 真正的迭代器...........45 第8章编译·运行·调试47 8.1 require函数.................49 8.2 C Packages.................50 8.3 错误........51 8.4 异常和错误处理.......52 8.5 错误信息和回跟踪(Tracebacks)....53 第9章协同程序................56 9.1 协同的基础...............56 9.2 管道和过滤器...........58 9.3 用作迭代器的协同...61 9.4 非抢占式多线程.......63 第10章完整示例..............68 10.1 Lua作为数据描述语言使用........68 10.2 马尔可夫链算法.....71 第二篇 tables与objects........75 第11章数据结构..............76 11.1 数组......76 11.2 阵和多维数组.........77 11.3 链表......78 11.4 队列和双端队列.....78 11.5 集合和包.................80 11.6 字符串缓冲.............80 第12章数据文件与持久化..................84 12.1 序列化...86 Programming in Lua v Copyright ® 2005, Translation Team, www.luachina.net 第13章 Metatables and Metamethods...92 13.1 算术运算的Metamethods............92 13.2 关系运算的Metamethods............95 13.3 库定义的Metamethods................96 13.4 表相关的Metamethods................97 第14章环境..103 14.1 使用动态名字访问全局变量...103 14.2声明全局变量........104 14.3 非全局的环境.......106 第15章 Packages.............109 15.1 基本方法...............109 15.2 私有成员(Privacy)................111 15.3 包与文件................112 15.4 使用全局表............113 15.5 其他一些技巧(Other Facilities)...115 第16章面向对象程序设计.................118 16.1 类.........119 16.2 继承.....121 16.3 多重继承...............122 16.4 私有性(privacy)...................125 16.5 Single-Method的对象实现方法127 第17章 Weak表...............128 17.1 记忆函数...............130 17.2 关联对象属性.......131 17.3 重述带有默认值的表...............132 第三篇标准库134 第18章数学库................135 第19章 Table库...............136 19.1数组大小................136 19.2 插入/删除..............137 19.3 排序.....137 第20章 String库..............140 20.1 模式匹配函数.......141 20.2 模式.....143 20.3 捕获(Captures).146 20.4 转换的技巧(Tricks of the Trade)151 第21章 IO库..157 21.1 简单I/O模式..........157 21.2 完全I/O 模式........160 Programming in Lua vi Copyright ® 2005, Translation Team, www.luachina.net 第22章操作系统库........165 22.1 Date和Time............165 22.2 其它的系统调用...167 第23章 Debug库..............169 23.1 自省(Introspective)..............169 23.2 Hooks...173 23.3 Profiles.174 第四篇 C API..177 第24章 C API纵览..........178 24.1 第一个示例程序...179 24.2 堆栈.....181 24.3 C API的错误处理..186 第25章扩展你的程序....188 25.1 表操作.189 25.2 调用Lua函数.........193 25.3 通用的函数调用...195 第26章调用C函数..........198 26.1 C 函数..198 26.2 C 函数库................200 第27章撰写C函数的技巧..................203 27.1 数组操作...............203 27.2 字符串处理...........204 27.3 在C函数中保存状态.................207 第28章 User-Defined Types in C........212 28.1 Userdata.................212 28.2 Metatables..............215 28.3 访问面向对象的数据...............217 28.4 访问数组...............219 28.5 Light Userdata........220 第29章资源管理............222 29.1 目录迭代器...........222 29.2 XML解析...............225
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值