Lua Starter

mahua 标签: Lua #Lua starter Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。html

##Lua 应用场景 游戏开发 独立应用脚本 Web 应用脚本 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统shell

##Hello world!数据库

print("Hello World")

##注释数组

--行注释
	--[[
    	块注释
	--]]

##变量 ###全局变量 *默认即为全局变量,无需声明符号 *访问未定义的全局变量不出错 *删除全局变量将其赋值为nil(等同于其余语言NULL)便可安全

a=10 --全局变量
	print(a) --10

	a=nil --删除该变量
	print(a) --nil

###局部变量数据结构

  • 局部变量的做用域为从声明位置开始到所在语句块结束(或者是直到下一个同名局部变量的声明)。
local data = 100;

	local function fun1()
		print(data);
		data = data+50;
	end

	data = 200;

	local data = 300; -- 从新定义一个局部变量

	local function fun2()
		print(data);
		data = data+50;
	end

	data = 400;

	--调用
	fun1(); -- 200
	fun2(); -- 400
	fun1(); -- 250
	fun2(); -- 450

###赋值闭包

a, b = 10, 2*x
	x, y = y, x                     -- swap 'x' for 'y'
	a[i], a[j] = a[j], a[i]         -- swap 'a[i]' for 'a[i]'

	-[[赋值多个的时候,以下规则
		a. 变量个数 > 值的个数             按变量个数补足nil
		b. 变量个数 < 值的个数             多余的值会被忽略
		]]
	a, b, c = 0, 1
	print(a,b,c)             --> 0   1   nil
	 
	a, b = a+1, b+1, b+2     -- value of b+2 is ignored
	print(a,b)               --> 1   2
	 
	a, b, c = 0 			 --> 易错!注意!!!
	print(a,b,c)             --> 0   nil   nil

###索引app

t[i]
	t.i                 -- 当索引为字符串类型时的一种简化写法
	gettable_event(t,i) -- 采用索引访问本质上是一个相似这样的函数调用

##数据类型 | 类型 | 说明 | | -------- | -----: | | nil | 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中至关于false)。| | boolean | 包含两个值:false和true。| | number | 表示双精度类型的实浮点数| | string | 字符串由一对双引号或单引号来表示| | function | 由 C 或 Lua 编写的函数| | userdata | 表示任意存储在变量中的C数据结构| | thread | 表示执行的独立线路,用于执行协同程序| | table Lua | 中的表(table)实际上是一个"关联数组"(associative arrays),数组的索引能够是数字或者是字符串。在 Lua 里,table 的建立是经过"构造表达式"来完成,最简单构造表达式是{},用来建立一个空表。|ide

--可用type查看类型
	print(type("Hello world"))      --> string
	print(type(10.4*3))             --> number
	print(type(print))              --> function
	print(type(type))               --> function
	print(type(true))               --> boolean
	print(type(nil))                --> nil
	print(type(type(X)))            --> string

###nil nil 类型表示一种没有任何有效值,它只有一个值 -- nil,例如打印一个没有赋值的变量,便会输出一个 nil 值:函数

print(type(a)) -- nil

对于全局变量和 table,nil 还有一个"删除"做用,给全局变量或者 table 表里的变量赋一个 nil 值,等同于把它们删掉,执行下面代码就知:

tab1 = { key1 = "val1", key2 = "val2", "val3" }
	for k, v in pairs(tab1) do
	    print(k .. " - " .. v)
	end
	 
	tab1.key1 = nil
	for k, v in pairs(tab1) do
	    print(k .. " - " .. v) --不会打印key1了
	end

###bool类型

  • boolean 类型只有两个可选值:true(真) 和 false(假),Lua 把 false 和 nil 看做是"假",其余的都为"真":
print(type(true))
	print(type(false))
	print(type(nil))
	 
	if false or nil then
	    print("至少有一个是 true")
	else
	    print("false 和 nil 都为 false!") --false 和 nil 都为 false!
	end

###number

  • Lua 默认只有一种 number 类型 -- double(双精度)类型(默认类型能够修改 luaconf.h 里的定义),
print(type(2))
	print(type(2.2))
	print(type(0.2))
	print(type(2e+1))
	print(type(0.2e-1))
	print(type(7.8263692594256e-06))

###string

string1 = "this is string1"
	--[[能够输出换行的string]]
	html = [[
			<html>
			<head></head>
			<body>
			    <a href="http://www.w3cschool.cc/">w3cschool菜鸟教程</a>
			</body>
			</html>
			]]
	print(html)

	--算数操做Lua尝试转换为number进行操做
	print("1"+2) --3.0

	--字符串链接用..
	print("1".."2") --12

	--符号#可计算字符串长度
	print(#html)

###table(表)

  • 在 Lua 里,table (相似于map,将list与map结合起来)的建立是经过"构造表达式"来完成,最简单构造表达式是{},用来建立一个空表。也能够在表里添加一些数据,直接初始化表:
-- 建立一个空的 table
	local tbl1 = {}
	 
	-- 直接初始表 index由1开始
	local tbl2 = {"apple", "pear", "orange", "grape"}
	for key, val in pairs(tbl2) do
	    print("Key", key, val)
	end

	a = {}
	a["key"] = "value" --保存一个键值对 "key":"value"
	key = 10
	a[key] = 22			--10:22
	a[key] = a[key] + 11
	for k, v in pairs(a) do --两个键值对
	    print(k .. " : " .. v)
	end
  • table 不会固定长度大小,有新数据添加时 table 长度会自动增加,没初始的 table 都是 nil。
a3 = {}
	for i = 1, 10 do
	    a3[i] = i
	end
	a3["key"] = "val"
	print(a3["key"])  --val
	print(a3["none"]) --nil

###function(函数)

function factorial1(n)
	    if n == 0 then
	        return 1
	    else
	        return n * factorial1(n - 1)
	    end
	end
	print(factorial1(5))
	factorial2 = factorial1
	print(factorial2(5))
  • function 能够以匿名函数(anonymous function)的方式经过参数传递:
function anonymous(tab, fun)
	    for k, v in pairs(tab) do
	        print(fun(k, v))
	    end
	end
	tab = { key1 = "val1", key2 = "val2" }
	anonymous(tab, function(key, val)
	    return key .. " = " .. val
	end)

###thread(线程) 在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差很少,拥有本身独立的栈、局部变量和指令指针,能够跟其余协同程序共享全局变量和其余大部分东西。 线程跟协程的区别:线程能够同时多个运行,而协程任意时刻只能运行一个,而且处于运行状态的协程只有被挂起(suspend)时才会暂停。

###userdata(自定义类型)

userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所建立的类型,能够将任意 C/C++ 的任意数据类型的数据(一般是 struct 和 指针)存储到 Lua 变量中调用。

##循环 ###while

a=10
while( a < 20 )
do
   print("a 的值为:", a)
   a = a+1
end

###for

for var=exp1,exp2,exp3 do  
    <执行体>  
end  
--var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,若是不指定,默认为1。

--eg.
for i=1,f(x) do --此处的f(x)只会在初始化循环时候执行一次
    print(i)
end
 
for i=10,1,-1 do
    print(i)
end

--f(x)的例子
function f(x)  
    print("function")  
    return x*2   
end  
for i=1,f(5) do print(i)  
end  
--[[
function
1
2
3
4
5
6
7
8
9
10
--]]

###泛型for循环

--打印数组a的全部值  
a = {"Lua", "Tutorial"}
for i,v in ipairs(a) 
	do print(i..v) 
end  
--i是数组索引值,v是对应索引的数组元素值。ipairs是Lua提供的一个迭代器函数,用来迭代数组。

###repeat...until(相似do while)

--[ 变量定义 --]
a = 10
--[ 执行循环 --]
repeat
   print("a的值为:", a)
   a = a + 1
until( a > 15 )

###不一样循环能够嵌套

j =2
for i=2,10 do
   for j=2,(i/j) , 2 do
      if(not(i%j)) 
      then
         break 
      end
      if(j > (i/j))then
         print("i 的值为:",i)
      end
   end
end

###break

--[ 定义变量 --]
a = 10

--[ while 循环 --]
while( a < 20 )
do
   print("a 的值为:", a)
   a=a+1
   if( a > 15)
   then
      --[ 使用 break 语句终止循环 --]
      break
   end
end

##流程控制

--[ 定义变量 --]
a = 100

--[ 检查布尔条件 --]
if( a == 10 )
then
   --[ 若是条件为 true 打印如下信息 --]
   print("a 的值为 10" )
else if( a == 20 )
then   
   --[ if else if 条件为 true 时打印如下信息 --]
   print("a 的值为 20" )
else if( a == 30 )
then
   --[ if else if condition 条件为 true 时打印如下信息 --]
   print("a 的值为 30" )
else
   --[ 以上条件语句没有一个为 true 时打印如下信息 --]
   print("没有匹配 a 的值" )
end
print("a 的真实值为: ", a )

##函数

--实例
--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   return result; 
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))

###函数做为参数

myprint = function(param)
   print("这是打印函数 -   ##",param,"##")
end

function add(num1,num2,functionPrint)
   result = num1 + num2
   -- 调用传递的函数参数
   functionPrint(result)
end
myprint(10)
-- myprint 函数做为参数传递
add(2,5,myprint)

###多返回值

s, e = string.find("w3cschool菜鸟教程:www.w3cschool.cc", "菜鸟教程") print(s,e)
function maximum (a)
    local mi = 1             -- 最大值索引
    local m = a[mi]          -- 最大值
    for i,val in ipairs(a) do
       if val > m then
           mi = i
           m = val
       end
    end
    return m, mi
end

print(maximum({8,10,23,12,5}))

###可变参数

function average(...)
   result = 0
   local arg={...}
   for i,v in ipairs(arg) do
      result = result + v
   end
   --#arg 表示传入参数的个数
   print("总共传入 " .. #arg .. " 个数")
   return result/#arg
end

print("平均值为",average(10,5,3,4,5,6))

##运算符 ###算数

a = 21
b = 10
c = a + b
print("Line 1 - c 的值为 ", c )
c = a - b
print("Line 2 - c 的值为 ", c )
c = a * b
print("Line 3 - c 的值为 ", c )
c = a / b
print("Line 4 - c 的值为 ", c )
c = a % b
print("Line 5 - c 的值为 ", c )
c = a^2
print("Line 6 - c 的值为 ", c )
c = -a
print("Line 7 - c 的值为 ", c )

--[[
Line 1 - c 的值为 	31
Line 2 - c 的值为 	11
Line 3 - c 的值为 	210
Line 4 - c 的值为 	2.1
Line 5 - c 的值为 	1
Line 6 - c 的值为 	441
Line 7 - c 的值为 	-21
--]]

###关系

a = 21
b = 10

if( a == b )
then
   print("Line 1 - a 等于 b" )
else
   print("Line 1 - a 不等于 b" )
end

if( a ~= b )
then
   print("Line 2 - a 不等于 b" )
else
   print("Line 2 - a 等于 b" )
end

if ( a < b )
then
   print("Line 3 - a 小于 b" )
else
   print("Line 3 - a 大于等于 b" )
end

if ( a > b ) 
then
   print("Line 4 - a 大于 b" )
else
   print("Line 5 - a 小于等于 b" )
end

-- 修改 a 和 b 的值
a = 5
b = 20
if ( a <= b ) 
then
   print("Line 5 - a 小于等于  b" )
end

if ( b >= a ) 
then
   print("Line 6 - b 大于等于 a" )
end

###逻辑

a = true
b = true

if ( a and b )
then
   print("a and b - 条件为 true" )
end

if ( a or b )
then
   print("a or b - 条件为 true" )
end

print("---------分割线---------" )

-- 修改 a 和 b 的值
a = false
b = true

if ( a and b )
then
   print("a and b - 条件为 true" )
else
   print("a and b - 条件为 false" )
end

if ( not( a and b) )
then
   print("not( a and b) - 条件为 true" )
else
   print("not( a and b) - 条件为 false" )
end

###特殊

a = "Hello "
b = "World"

print("链接字符串 a 和 b ", a..b )

print("b 字符串长度 ",#b )

print("字符串 Test 长度 ",#"Test" )

print("w3cschool菜鸟教程网址长度 ",#"www.w3cschool.cc" )

##字符串 ###示例

string1 = "Lua"
print("\"字符串 1 是\"",string1)
string2 = 'w3cschool.cc'
print("字符串 2 是",string2)

string3 = [["Lua 教程"]]
print("字符串 3 是",string3)

###字符串经常使用操做

--转大写
print(string.upper("abc"))

--转小写
print(string.upper("ABC"))

--替换字符串 数字表示替换次数,忽略则所有替换
print(string.gsub("abcabc",'c','d',1))

--字符串查找 数字为起始位置,找到则返回起止位置
print(string.find("abcabc",'a',3))

--字符串反转
print(string.reverse("12345"))

--格式化字符串
string.format("the value is:%d",4)

--数字转换为字符串并链接
print(string.char(97,98,99,100))

--byte转换为整数,可指定位置,默认为1
print(string.byte("abc",2))

--计算长度 同#"string"
print(string.len("abc")==#"abc")

--返回字符串的n个拷贝
print(string.rep('a', 3))

--链接字符串
print("aaa"..'bbb')

##数组 ###一维

array = {"Lua", "Tutorial"}

--Lua 索引值是以 1 为起始,但你也能够指定 0 开始。
for i= 0, 2 do
   print(array[i])
end

--也能够用负数做为索引
array = {}

for i= -2, 2 do
   array[i] = i *2
end

for i = -2,2 do
   print(array[i])
end

###多维

-- 初始化数组
array = {}
for i=1,3 do
    array[i] = {}
      for j=1,3 do
         array[i][j] = i*j
    end
end

-- 访问数组
for i=1,3 do
   for j=1,3 do
      print(array[i][j])
   end
end

##迭代器 ###内置简单迭代

array = {"Lua", "Tutorial"}

for key,value in ipairs(array) 
do
   print(key, value)
end

###自定义的迭代器

function square(iteratorMaxCount,currentNumber)
   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
   return currentNumber, currentNumber*currentNumber
   end
end

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

###利用闭包实现的迭代器

array = {"Lua", "Tutorial"}

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

##Lua table

  • table 是 Lua 的一种数据结构用来帮助咱们建立不一样的数据类型,如:数字、字典等。
  • Lua table 使用关联型数组,你能够用任意类型的值来做数组的索引,但这个值不能是 nil。
  • Lua table 是不固定大小的,你能够根据本身须要进行扩容。
  • Lua也是经过table来解决模块(module)、包(package)和对象(Object)的。 例如string.format表示使用"format"来索引table string。

###初始化与销毁

-- 初始化表
mytable = {}

-- 指定值
mytable[1]= "Lua"

-- 移除引用
mytable = nil
-- lua 垃圾回收会释放内存

###table的引用(相似Java)

-- 简单的 table 演示table类型的引用相似Java
mytable = {}
print("mytable 的类型是 ",type(mytable))

mytable[1]= "Lua"
mytable["wow"] = "修改前"
print("mytable 索引为 1 的元素是 ", mytable[1])
print("mytable 索引为 wow 的元素是 ", mytable["wow"])

-- alternatetable和mytable的是指同一个 table
alternatetable = mytable

print("alternatetable 索引为 1 的元素是 ", alternatetable[1])
print("mytable 索引为 wow 的元素是 ", alternatetable["wow"])

alternatetable["wow"] = "修改后"

print("mytable 索引为 wow 的元素是 ", mytable["wow"])

-- 释放变量
alternatetable = nil
print("alternatetable 是 ", alternatetable)

-- mytable 仍然能够访问
print("mytable 索引为 wow 的元素是 ", mytable["wow"])

mytable = nil
print("mytable 是 ", mytable)

###table操做

--链接table中的全部元素,利用分隔符
t1={"a","b","c"}

print(table.concat(t1))

print(table.concat(t1,"@@"))

print(table.concat(t1,"@@",1,2))

--插入元素
table.insert(t1,"d")

print(t1[4])

table.insert(t1,2,"b")

print(t1[2])

--删除元素

print("当前元素:"..table.concat(t1,","))

table.remove(t1)

print("remove(t1)默认删除最后一个元素,当前元素:"..table.concat(t1,","))

table.remove(t1,1)

print("remove(t1,1)以后"..table.concat(t1,","))

--排序
t1={"c","b","a"}

print("排序前:"..table.concat(t1,","))

table.sort(t1)

print("排序后:"..table.concat(t1,","))

###!!!慎用"#table"

  • 不要赋值nil,删除元素请使用remove
  • 元素不是同一类型length无明确意义
tbl = {"a", "b","c"}

print("tbl 长度 ", #tbl) --3

tbl = {"a", "b","c"="bb"}

print("tbl 长度 ", #tbl) --2

tbl = {"a", "b",nil}

print("tbl 长度 ", #tbl) --2

tbl = {"a", nil,"b",nil} --1

print("tbl 长度 ", #tbl)

##模块与包 ###自定义包

-- 文件名为 module.lua
-- 定义一个名为 module 的模块
module = {}
 
-- 定义一个常量
module.constant = "这是一个常量"
 
-- 定义一个函数
function module.func1()
    io.write("这是一个公有函数!\n")
end
 
local function func2()
    print("这是一个私有函数!")
end
 
function module.func3()
    func2()
end
 
return module
--使用自定义包
require("module")

print(module.constant)

module.func3()
--设置别名
local m = require("module")
 
print(m.constant)
 
m.func3()

###加载策略

  • require 用于搜索 Lua 文件的路径是存放在全局变量 package.path 中,当 Lua 启动后,会以环境变量LUA_PATH的值来初始这个环境变量。若是没有找到该环境变量,则使用一个编译时定义的默认路径来初始化。
#LUA_PATH
export LUA_PATH="~/lua/?.lua;;"

##元表

  • 元表就是在table上加上自定义的对表数据的操做 ###__index
--__index元方法查看表中元素是否存在,若是不存在,返回结果为nil;若是存在则由__index 返回结果。
mytable = setmetatable({key1 = "value1"}, {
  __index = function(mytable, key)
    if key == "key2" then
      return "metatablevalue"
    else
      return mytable[key]
    end
  end
})

print(mytable.key1,mytable.key2)

###__newindex

--当你给表的一个缺乏的索引赋值,解释器就会查找__newindex元方法:若是存在则调用这个函数而不进行赋值操做。

mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })

print(mytable.key1)

mytable.newkey = "新值2"
print(mytable.newkey,mymetatable.newkey)

mytable.key1 = "新值1"
print(mytable.key1,mymetatable.key1)

mytable = setmetatable({key1 = "value1"}, {
  __newindex = function(mytable, key, value)
		rawset(mytable, key, "\""..value.."\"")

  end
})
--使用rawset 函数来更新表
mytable.key1 = "new value"
mytable.key2 = 4

print(mytable.key1,mytable.key2)

###__add

--为表添加操做符
-- 自定义计算表中最大值函数 table_maxn
function table_maxn(t)
    local mn = 0
    for k, v in pairs(t) do
        if mn < k then
            mn = k
        end
    end
    return mn
end

-- 两表相加操做(合并)
mytable = setmetatable({ 1, 2, 3 }, {
  __add = function(mytable, newtable)
    for i = 1, table_maxn(newtable) do
      table.insert(mytable, table_maxn(mytable)+1,newtable[i])
    end
    return mytable
  end
})

secondtable = {4,5,6}

mytable = mytable + secondtable
	for k,v in ipairs(mytable) do
print("index:"..k,v)
end

--[[
__add	对应的运算符 '+'.
__sub	对应的运算符 '-'.
__mul	对应的运算符 '*'.
__div	对应的运算符 '/'.
__mod	对应的运算符 '%'.
__unm	对应的运算符 '-'.
__concat	对应的运算符 '..'.
__eq	对应的运算符 '=='.
__lt	对应的运算符 '<'.
__le	对应的运算符 '<='.

--]]

###__call

--__call元方法
-- 计算表中最大值,table.maxn在Lua5.2以上版本中已没法使用
-- 自定义计算表中最大值函数 table_maxn
function table_maxn(t)
    local mn = 0
    for k, v in pairs(t) do
        if mn < k then
            mn = k
        end
    end
    return mn
end

-- 定义元方法__call
mytable = setmetatable({10}, {
  __call = function(mytable, newtable)
	sum = 0
	for i = 1, table_maxn(mytable) do
		sum = sum + mytable[i]
	end
    for i = 1, table_maxn(newtable) do
		sum = sum + newtable[i]
	end
	return sum
  end
})
newtable = {10,20,30}
print(mytable(newtable))

###__tostring

--__tostring 元方法用于修改表的输出行为
mytable = setmetatable({ 10, 20, 30 }, {
  __tostring = function(mytable)
    sum = 0
    for k, v in pairs(mytable) do
		sum = sum + v
	end
    return "表全部元素的和为 " .. sum
  end
})
print(mytable)

##协同(coroutine)

--协程
-- coroutine_test.lua 文件

--create建立一个协程,未调用以前为阻塞状态
--此时co是协程对象
co = coroutine.create(
    function(i)
        print(i);
    end
)

print(coroutine.status(co))  -- suspended

--与create配合使用唤醒协程进行传参
coroutine.resume(co, 1)   -- 1
print(coroutine.status(co))  -- dead
 
print("----------")
 
--wrap返回一个函数a,调用a()则进入协程并传递参数
--此时co表示一个函数
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()) --返回正在运行的线程号 thread:XXXXXX
            end
            coroutine.yield()--挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有不少有用的效果
        end
    end
)
 
coroutine.resume(co2) --1
coroutine.resume(co2) --2
coroutine.resume(co2) --3
 
print(coroutine.status(co2))   -- suspended
print(coroutine.running())
 
print("----------")

###resume与create的配合 注意resume与yield的参数传递

function foo (a)
    print("foo 函数输出", a)
    return coroutine.yield(2 * a) -- 返回  2*a 的值
end
 
co = coroutine.create(function (a , b)
    print("第一次协同程序执行输出", a, b) -- co-body 1 10
    local r = foo(a + 1)
     
    print("第二次协同程序执行输出", r)
    local r, s = coroutine.yield(a + b, a - b)  -- a,b的值为第一次调用协同程序时传入
     
    print("第三次协同程序执行输出", r, s)
    return b, "结束协同程序"                   -- b的值为第二次调用协同程序时传入
end)
        
--首次启动协同程序,参数传递给函数
print("main", coroutine.resume(co, 1, 10)) -- true, 4

--第二次唤醒协同程序,参数传递给上一次的yield() line:3
print("main", coroutine.resume(co, "r")) -- true 11 -9

--第三次唤醒协同程序,参数传递给上一次的yield() line:11
print("main", coroutine.resume(co, "x", "y")) -- true 10 end

print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine

###生产者-消费者

local newProductor

function productor()
     local i = 0
     while true do
          i = i + 1
          send(i)     -- 将生产的物品发送给消费者
     end
end

function consumer()
     while true do
          local i = receive()     -- 从生产者那里获得物品
          print(i)
     end
end

function receive()
     local status, value = coroutine.resume(newProductor)
     return value
end

function send(x)
     coroutine.yield(x)     -- x表示须要发送的值,值返回之后,就挂起该协同程序
end

-- 启动程序
newProductor = coroutine.create(productor)
consumer()

##IO

###简单模式(类c语言)

--lua文件IO简单模式 相似c语言
--[[
file = io.open (filename [, mode])
r	以只读方式打开文件,该文件必须存在。
w	打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则创建该文件。
a	以附加的方式打开只写文件。若文件不存在,则会创建该文件,若是文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
r+	以可读写方式打开文件,该文件必须存在。
w+	打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则创建该文件。
a+	与a相似,但此文件可读可写
b	二进制模式,若是文件是二进制文件,能够加上b
+	号表示对文件既能够读也能够写
--]]

--
-- 以只读方式打开文件
file = io.open("test.txt", "r")

-- 设置默认输入文件为 test.lua
io.input(file)

-- 读取一个数字
print(io.read("*n"))

-- 读取n个字符
print(io.read(2))

-- 输出文件下一行 默承认不写,当前位置读取至换行止
print(io.read("*l"))

-- 从当前位置读取整个文件
print(io.read("*a"))

-- 关闭打开的文件
io.close(file)

-- 以附加的方式打开只写文件
file = io.open("test.lua", "a")

-- 设置默认输出文件为 test.lua
io.output(file)

-- 在文件最后一行添加 Lua 注释
io.write("--  test.lua 文件末尾注释")

-- 关闭打开的文件
io.close(file)

####其余的IO函数

  • io.tmpfile():返回一个临时文件句柄,该文件以更新模式打开,程序结束时自动删除
  • io.type(file): 检测obj是否一个可用的文件句柄
  • io.flush(): 向文件写入缓冲中的全部数据
  • io.lines(optional file name):返回一个迭代函数,每次调用将得到文件中的一行内容,当到文件尾时,将返回nil,但不关闭文件

###彻底模式 IO.xxx变为file.xxx

-- 以只读方式打开文件
file = io.open("test.lua", "r")

-- 输出文件第一行
print(file:read())

-- 关闭打开的文件
file:close()

-- 以附加的方式打开只写文件
file = io.open("test.lua", "a")

-- 在文件最后一行添加 Lua 注释
file:write("--test")

-- 关闭打开的文件
file:close()
  • file:seek(optional whence, optional offset) 设置和获取当前文件位置
  • file:flush(): 向文件写入缓冲中的全部数据
  • io.lines(optional file name)打开指定的文件filename为读模式并返回一个迭代函数,每次调用将得到文件中的一行内容,当到文件尾时,将返回nil,并自动关闭文件。
-- 以只读方式打开文件
file = io.open("test.lua", "r")
-- 从倒数25位置开始读取整个文件内容
file:seek("end",-25)
print(file:read("*a"))

-- 关闭打开的文件
file:close()
for line in io.lines("test.lua") do

print(line)

end

##错误处理 ###assert与error

local function add(a,b)
   assert(type(a) == "number", "a is not a number")
   assert(type(b) == "number", "b is not a number")
   
   if(a==b) then 
   -- error终止正在执行的函数,返回message,第二个参数为0,1,2
   -- 表示0:不添加错误位置信息;1(默认):调用error位置(文件+行号)
   -- 2:指出哪一个调用error的函数的函数
      error("err",2)
   end
   return a+b
end
print(add(10,20))

###pcall与xpcall

--pcall表示保护模式运行程序,第一个参数为函数,第二个参数为函数的参数
pcall(function(i) print(i) end, aa==1)
--无错误返回true,有错误返回false,err_info
has_err,err_info=pcall(function(i) print(i) error('error..') end, 33)
print(has_err,err_info)

--xpcall提供更详细的信息
function myfunction ()
   n = n/nil
end

function myerrorhandler( err )
    print( "ERROR:", err )
end

status = xpcall( myfunction, myerrorhandler )
print( status)

##垃圾回收 lua为自动垃圾回收

  • collectgarbage("collect"): 作一次完整的垃圾收集循环。经过参数 opt 它提供了一组不一样的功能:
  • collectgarbage("count"): 以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分,因此只须要乘上 1024 就能获得 Lua 使用的准确字节数(除非溢出)。
  • collectgarbage("restart"): 重启垃圾收集器的自动运行。
  • collectgarbage("setpause"): 将 arg 设为收集器的 间歇率 (参见 §2.5)。 返回 间歇率 的前一个值。
  • collectgarbage("setstepmul"): 返回 步进倍率 的前一个值。
  • collectgarbage("step"): 单步运行垃圾收集器。 步长"大小"由 arg 控制。 传入 0 时,收集器步进(不可分割的)一步。 传入非 0 值, 收集器收集至关于 Lua 分配这些多(K 字节)内存的工做。 若是收集器结束一个循环将返回 true 。
  • collectgarbage("stop"): 中止垃圾收集器的运行。 在调用重启前,收集器只会因显式的调用运行。

##面向对象

-- 面向对象,使用table模拟实现
-- Meta class
Shape = {area = 0}

-- 基础类方法 new
function Shape:new (o,side)
  o = o or {}
  -- self相似this
  setmetatable(o, self)
  self.__index = self
  side = side or 0
  self.area = side*side;
  return o
end

-- 基础类方法 printArea
function Shape:printArea ()
  print("面积为 ",self.area)
end

-- 建立对象
myshape = Shape:new(nil,10)

myshape:printArea()

###继承与方法重写

-- Meta class
Shape = {area = 0}
-- 基础类方法 new
function Shape:new (o,side)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  side = side or 0
  self.area = side*side;
  return o
end
-- 基础类方法 printArea
function Shape:printArea ()
  print("面积为 ",self.area)
end

-- 建立对象
myshape = Shape:new(nil,10)
myshape:printArea()

Square = Shape:new()
-- 派生类方法 new
function Square:new (o,side)
  o = o or Shape:new(o,side)
  setmetatable(o, self)
  self.__index = self
  return o
end

-- 派生类方法 printArea 重写
function Square:printArea ()
  print("正方形面积为 ",self.area)
end

-- 建立对象
mysquare = Square:new(nil,10)
mysquare:printArea()

Rectangle = Shape:new()
-- 派生类方法 new
function Rectangle:new (o,length,breadth)
  o = o or Shape:new(o)
  setmetatable(o, self)
  self.__index = self
  self.area = length * breadth
  return o
end

-- 派生类方法 printArea
function Rectangle:printArea ()
  print("矩形面积为 ",self.area)
end

-- 建立对象
myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()
相关文章
相关标签/搜索