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()
相關文章
相關標籤/搜索