來源: programming-in-lua-2ed.pdf
更新記錄
item | note |
---|---|
20160817 | 第一版 |
目錄
- Chapter 1
- Types and Values
- String
- Table
- Chapter 3 Expressions
- Chapter 4 Statement
- 4-3 Control Structures
- Chapter5 Function
- Chapter 6 -More About Function
- Chapter7 Iterator and the Generic for
- Chapter8 Compilation,Excution,and Errors
- Chapter9 Coroutines (協同程序)
- Chapter 11 Data Structures
- PARTIII; The Standard Library (待增加)
- PARTIV; The C API (待增加)
- 其它
- 參考來源
Chapter 1
Chunks
- Each piece of code that Lua executes, such as a file or a single line in interac-tive mode, is called a chunk.
- A chunk is simply a sequence of commands (or statements).
- 單行的程式
可以使用分號(semicolon)也可以不使用分號1
2
3
4
5
6a = 1
b = a*2
a = 1;
b = a*2;
a = 1; b = a*2
a = 1 b = a*2 -- ugly, but valid
Some Lexical Conventions (词法约定)
- 變數定義不可以使用數字開頭
- 變數定義可以使用低線(_)開頭
1
2i j i10 _ij
aSomewhatLongName _INPUT
Global Variables
- 預設定義為全域變數
- 沒有定義的變數使用時將會回傳nil
1
2
3print(b) --> nil
b = 10
print(b) --> 10
Types and Values
basic types
eight basic types in Lua:
- nil : 表示未初始化的變數
變數若設定為nil,即為刪除變數 - boolean : false or true
只有false及nil會回傳false, 其它為true - number : 數字
ex. 4 0.4 4.57e-3 0.3e12 5e+20 - string : 字串
- userdata,
- function
- thread
table.
1
2
3
4
5
6
7print(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))) --> stringtype(x)回傳為字串
String
- Strings in Lua are immutable values
表示不能去修改字串內容,需要產生一個新的字串內容以符合需求1
2
3
4a = "one string"
b = string.gsub(a, "one", "another") -- change string parts
print(a) --> one string
print(b) --> another string
使用 [[ 及 ]] 定義多行字串內容
- 使用 [[ 及 ]] 定義多行字串內容
1
2
3
4
5
6
7
8
9
10page = [[
<html>
<head>
<title>An HTML Page</title>
</head>
<body>
<a href="http://www.lua.org">Lu
</body>
</html>
]]
concatenation operator(連接運算符號)
- The .. is the string concatenation operator in Lua
1
print(10 .. 20) --> 1020
取得字串長度
- In Lua 5.1, you can get the length of a string using the operator `#’
1
2
3
4
5
6
7a = "hello"
print(#a) --> 5
print(#"good\0bye") --> 8
for i=1, #a do
print(a[i])
end
Table
table { } 實現一個array,此array可以存放number,string或其它,但不可以是nil
1
2
3
4
5
6
7
8
9a = {} -- create a table and store its reference in 'a'
k = "x"
a[k] = 10 -- new entry, with key="x" and value=10
a[20] = "great" -- new entry, with key=20 and value="great"
print(a["x"]) --> 10
k = 20
print(a[k]) --> "great"
a["x"] = a["x"] + 1 -- increments entry "x"
print(a["x"]) --> 11providing a.name as syntactic sugar for a[“name”]
1
2
3a.x = 10 -- same as a["x"] = 10
print(a.x) -- same as print(a["x"])
print(a.y) -- same as print(a["y"])
Chapter 3 Expressions
優先順序
seq | item |
---|---|
1 | ^ |
2 | not # - (unary) |
3 | * / % |
4 | + - |
5 | .. |
6 | < > <= >= ~= == |
7 | and |
8 | or |
- ex
1
2
3
4
5a+i < b/2+1 <--> (a+i) < ((b/2)+1)
5+x^2*8 <--> 5+((x^2)*8)
a < y and y <= z <--> (a < y) and (y <= z)
-x^2 <--> -(x^2)
x^y^z <--> x^(y^z)
3.6 Table Constructors
ex1
1
a = {x=10, y=20}
This previous line is equivalent to these commands:
1
a = {}; a.x=10; a.y=20
We can mix record-style and list-style initializations in the same constructor:
1
2
3
4
5
6polyline = {color="blue", thickness=2, npoints=4,
{x=0, y=0},
{x=-10, y=0},
{x=-10, y=1},
{x=0, y=1}
}Each of the elements polyline[i] is a table representing a record:
1
2print(polyline[2].x) --> -10
print(polyline[4].y) --> 1
Chapter 4 Statement
4-1 Assignment
Assignment is the basic means of changing the value
a = “hello” .. “world”
multiple assignment1
2
3a, 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[j]'無相對應到的變數,將會設定為nil(即除刪)
1
2a, b, c = 0, 1
print(a, b, c) --> 0 1 nil
4-2 Local Variables and Blocks
Besides global variables, Lua supports local variables
1
2j = 10 -- global variable
local i = 1 -- local variableUnlike global variables, local variables have their scope limited to the block
- It is good programming style to use local variables whenever possible
Local variables help you avoid cluttering the global environment with unnecessary names.1
2
3
4
5
6
7local a, b = 1, 10
if a < b then
print(a) --> 1
local a -- '= nil' is implicit
print(a) --> nil
end -- ends the block started at 'then'
print(a, b) --> 1 10
4-3 Control Structures
- if,while,repeat,for 等需要end表示結束(terminates)
- Lua treats as true all values different from false and nil
if then else
ex1
1
2
3
4
5
6if a < 0 then a = 0 end
if a < b then return a else return b end
if line > MAXLINES then
showpage()
line = 0
endex2
1
2
3
4
5
6
7
8
9
10
11if op == "+" then
r = a + b
elseif op == "-" then
r = a - b
elseif op == "*" then
r = a*b
elseif op == "/" then
r = a/b
else
error("invalid operation")
end
The for statement
由exp1到exp2, 每次增加exp3(若無exp3則預設值為1)
1
2
3for var=exp1,exp2,exp3 do
<something>
endex.
1
2for i=1,f(x) do print(i) end
for i=10,1,-1 do print(i) endIf you want to end a for loop before its normal termination, use break
- The generic for loop traverses all values returned by an iterator function:
1
2-- print all values of array 'a'
for i,v in ipairs(a) do print(v) end
4-4 break and return
- The break and return statements allow us to jump out of a block.
- This statement breaks the inner loop (for, repeat, or while) that contains it
1
2
3
4
5local i = 1
while a[i] do
if a[i] == v then break end
i = i + 1
end
Chapter5 Function
function
- function定義方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14a={[1]=11,[2]=12,[3]=10}
function add (a)
local sum = 0
for i,v in ipairs(a) do
sum = sum + v
end
return sum
end
print(add(a))
xx :[/tmp/tt]# lua t1.lua
33
function parameter
function f(a, b) return a or b end
CALL | PARAMETERS |
---|---|
f(3) | a=3, b=nil |
f(3, 4) | a=3, b=4 |
f(3, 4, 5) | a=3, b=4 (5 is discarded) |
如何設定給函數預設參數值
- 未給預參數值n, 則此時為nil
- 當未代入參數,則設定預設值n為1
1
2
3
4function incCount (n)
n = n or 1
count = count + n
end
Chapter 6 -More About Function
Lua為First Class Value
指任何程式中的實體(ex. function,object,..)
即表示:function可以被當成參數傳遞或回傳
絕大多數語言中,數值與基礎型別都是第一類物件,然而不同語言中對函數的區別很大
- C語言與C++中的函數不是第一類物件,因為在這些語言中函數不能在執行期創造,而必須在設計時全部寫好
- Scheme中的函數是第一類物件,因為可以用lambda語句來創造匿名函數並作為第一類物件來操作
Closure(閉合函數)
將函數寫在另一個函數裡面,內部函數可以取得外部變數中的區域變數
範例內容
c1及c2是同一個函數創建兩個不同的Closure
個自擁有區域變數i1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function newCounter()
local i = 0
return function ()
i = i + 1
return i
end
end
c1 = newCounter()
print(c1())
print(c1())
c2 = newCounter()
print(c2())
print(c1())
print(c2())執行結果
1
2
3
4
5
6gk350a :[/tmp/tt]# lua t2.lua
1
2
1
3
2
非全域的函數(non-global function)
- When we store a function into a local variable, we get a local function
- 此local function會被限制在某些做用區使用
package can use these local functions:
1
2
3local f = function(<param>)
<body>
end正確方式
1
2
3
4
5
6
7
8local fact
fact = function (n)
if n == 0 then return 1
else return n*fact(n-1)
end
end
print(fact(3))錯誤的方式
在recursive funtion時,lua變數需要提前宣告
在fact(n-1)時fact尚未定義,看來lua是無js的variable hositing方式1
2
3
4
5
6
7
8
9
10
11
12
13
14local fact = function (n)
if n == 0 then return 1
else return n*fact(n-1)
end
end
print(fact(3))
# lua local-fu.lua
lua: local-fu.lua:3: attempt to call global 'fact' (a nil value)
stack traceback:
local-fu.lua:3: in function 'fact'
local-fu.lua:7: in main chunk
[C]: ?此方式的寫法在node js是沒問題,看來lua及node js還有些不同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$ cat local-t1.js
var fact = function (n) {
if(n == 0){
return 1;
} else {
return n*fact(n-1);
}
}
console.log("tt");
console.log(fact(3));
$ node local-t1.js
tt
6
提前宣告
在indirect recursive funtion時,lua變數需要提前宣告
1 | local f,g -- ' forwared decalartions' |
函數允許多個回傳值(5-1 Multiple Results)
定義
1
2
3function foo0 () end -- returns no results
function foo1 () return "a" end -- returns 1 result
function foo2 () return "a","b" end -- returns 2 results用法
1
2
3x,y = foo2() -- x="a", y="b"
x = foo2() -- x="a", "b" is discar
x,y,z = 10,foo2() -- x=10, y="a", z="b"
Proper Tail Calls
Lua does tail-call elimination
Tail Calls 模式
在撰寫遞迴時,每次的遞迴呼叫都會導致新的Stack frame產生,導致整個呼叫所編譯出來的Call Stack過大
Tail Call算是一種演算法,指的是在該子程式的尾端再進行遞迴呼叫
目的是希望藉此不必再額外產生新的Stack frame;不過必非所有的程式語言都有支援這樣特性
出處:初探ECMAScript 61
2
3
4
5
6
7
8//es6
function fact(n,acc=1){
if (n <=1) return acc;
return factorial(n-1,n*acc);
}
console.log(fact(10000));範例
房間移動範例,目前有4間如下
使用tail calls寫法,讓程式更簡單1
2
3| room1 | room2 |
-------------------------
| room3 | room4 |範例程式
xx :[~]# cat room.lua1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39function room1()
print("entry room1")
local move = io.read()
if move == "south" then return room3()
elseif move == "east" then return room2()
else
print("invaild move")
return room1()
end
end
function room2()
print("entry room2")
local move = io.read()
if move == "south" then return room4()
elseif move == "west" then return room1()
else
print("invaild move")
return room2()
end
end
function room3()
print("entry room3")
local move = io.read()
if move == "north" then return room1()
elseif move == "east" then return room4()
else
print("invaild move")
return room3()
end
end
function room4()
print("entry room4")
print ("congratulations!");
end
room1()測試
:[~]# lua room.lua1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16entry room1
north
invaild move
entry room1
sorth
invaild move
entry room1
south
entry room3
north
entry room1
east
entry room2
south
entry room4
congratulations!
Chapter7 Iterator and the Generic for
如何使用Closure建立itera
iter = values(t)
此時建立Closure函數 (好處,不會響影其它的變數)
回傳nil則表示結束
$ cat chapter7-for.lua1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17function values (t)
local i = 0
return function () i = i + 1; return t[i] end
end
t = {10, 20, 30}
iter = values(t)
print(iter())
print(iter())
print(iter())
print(iter())
xx :[~]# lua chapter7-for.lua
10
20
30
niliterator: 與while一起使用
1
2
3
4
5
6
7
8
9
10
11
12
13function values (t)
local i = 0
return function () i = i + 1; return t[i] end
end
t = {10, 20, 30}
iter = values(t)
while true do
local element = iter()
if element == nil then break end
print(element)
endxx :[~]# lua chapter7-while.lua
1
2
310
20
30iterator: 與for一起使用
用更少變數,程式變更簡單 (不需要iter變數)
The generate for does all the bookkeeping for an iteration loop
it keeps the iterator function interanlly, so we do not need the itera variable
$ cat chapter7-for-t1.lua1
2
3
4
5
6
7
8
9function values (t)
local i = 0
return function () i = i + 1; return t[i] end
end
t = {10, 20, 30}
for element in values(t) do
print(element)
endxx :[~]# lua chapter7-for-t1.lua
1
2
310
20
30將目前輸入的單子找出來(只允語數字及字母), 且回傳每個找到的單字
使用itera closure方式,將整個功能獨立分開(不會影響主程式變數)
$ cat chapter7-words.lua1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24function allwords()
local line = io.read()
print('<1>line:',line) -- debug print
local pos = 1
return function ()
print('<2>line:',line,' ,pos:',pos) -- debug print
while line do
local s, e = string.find(line,"%w+", pos) -- string.find: 會回找到的s,e
if s then
pos = e + 1
return string.sub(line, s, e)
else
line = io.read()
print('<3>line:',line) -- debug print
pos = 1
end
end
return nil
end
end
for word in allwords() do
print(word)
endxx :[~]# lua chapter7-words.lua
string.find: 會回找到的s,e
pattern %w: represents all alphanumeric characters.
5.4.1 – Patterns1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23t11 t22 t33
<1>line: t11 t22 t33
<2>line: t11 t22 t33 ,pos: 1
t11
<2>line: t11 t22 t33 ,pos: 4
t22
<2>line: t11 t22 t33 ,pos: 8
t33
<2>line: t11 t22 t33 ,pos: 12
taa tbb tcc
<3>line: taa tbb tcc
taa
<2>line: taa tbb tcc ,pos: 4
tbb
<2>line: taa tbb tcc ,pos: 8
tcc
<2>line: taa tbb tcc ,pos: 12
##!!@@aa%%^^ ^^&& **((11
<3>line: ##!!@@aa%%^^ ^^&& **((11
aa
<2>line: ##!!@@aa%%^^ ^^&& **((11 ,pos: 9
11
<2>line: ##!!@@aa%%^^ ^^&& **((11 ,pos: 25
Chapter 7-2 The Semantics of the Generic for
- lua內部for語法動作程序
- use the generic for itself to keep the iteration state
- In this section we will see the facilities that the generic for offers to hold state
The syntax for the generic for is as follows
1
2
3for <var-list> in <exp-list>
<body>
endfor實際範例
1
for k,v in piars(t) do print(k,v) end
for內部會保存3個變數
- iterator function ( _f )
- invariant state ( _s )
- a control variable( _var )
More precisely, a construction like
1
for var_1,...,var_n in <explist> do <block> end
is equivalen to the following code:
實際程序如下,內部會保存3個變數(_f,_s,_var)需要回傳(_f,_s,_var)
此時以for而言內部只允了,儲存1狀態變數
(若_f裡面需要由外部帶入,兩個以上的變數,要如何做?)1
2
3
4
5
6
7
8do
local _f, _s, _var = <explist>
while true do
local var_1..., var_n = _f( _s, _var )
_var = _var_1
if _var == nil then break end
end
end
Chapter 7-3 無需儲存狀態的iterator (Stateless Iterators)
表示自身不保存任可狀態的選代器(iterator)
$cat chapter7-3-ipairs.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15local function iter (a,i)
i = i + 1
local v = a[i]
if v then
return i,v
end
end
function myipairs(a)
return iter, a, 0
end
a = {"one", "two", "three"}
for i,v in myipairs(a) do
print(i,v)
endxx :[~]# lua chapter7-3-ipairs.lua
1
2
31 one
2 two
3 three
Chapter 7-4 Iterators with Complex State
- 通常,Iteration需要保存許多狀態,但for只提供1個(invariant state)及1個控制變量(a control variable)用於狀態的保存
解決方式
- 1.使用clousre
- 2.或是將所有狀態打包為1個table,保存在(invariant state) -> 為此節要示範的例
$ cat chapter7-4-itra.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24local iterator
function allword()
local state = {line = io.read(), pos = 1}
return iterator, state
end
function iterator (state)
while state.line do
local s, e = string.find(state.line, "%w+", state.pos)
if s then
state.pos = e + 1
return string.sub(state.line, s, e)
else
state.line = io.read()
state.pos = 1
end
end
return nil
end
for word in allword() do
print(word)
endxx:[~]# lua chapter7-4-itra.lua
1
2
3
4t11 t22 t33
t11
t22
t33
Chapter 7-5 True Iterators (allword iterator)
$ cat chapter7-5-allword.lua
1
2
3
4
5
6
7
8function allwords(f)
for line in io.lines() do
for word in string.gmatch(line, "%w+") do
f(word)
end
end
end
allwords(print)xx :[~]# lua chapter7-5-allword.lua
1
2
3
4t11 t22 t33
t11
t22
t33
使用匿名函數做為參數輸入
$ cat chapter7-5-allword-t2.lua
1
2
3
4
5
6
7
8
9
10
11
12function allwords(f)
line = io.read()
for word in string.gmatch(line, "%w+") do
f(word)
end
end
local count = 0
allwords(function (w)
if w == "hello" then count = count +1 end
end)
print(count)xx :[~]# lua chapter7-5-allword-t2.lua
1
2t11 hello t22 hello t33
2
Chapter8 Compilation,Excution,and Errors
Lua允語由外部載入precompiles source code(ex. dofile )
Chapter8-1 Compilation
- dofile as a kind of primitive operation to run chunks of Lua code
- dofile is actually an auxiliary function
- loadfile does the hard work
- loadfile loads a Lua chunk from a file, but it does not run the chunk
- loadfile只是將代碼編譯,但不會執行,並且回傳一個函數返回
- loadfile不會引發錯誤(它是返回錯誤並不處理錯誤)
dofile可以看成下例功能
1
2
3
4function dofile (filename)
local f = assert (loadfile(filename))
return f()
enddofile ([filename])
Opens the named file and executes its contents as a Lua chunk.load (func [, chunkname])
Loads a chunk using function func to get its pieces.loadfile ([filename])
Similar to load, but gets the chunk from file filename or from the standard input, if no file name is given.
loadfile example
loadfile(“foo.lua”)
之後,函數foo完成編譯,但還沒定義f()
定義此foo function$ cat foo.lua
1
2
3function foo (x)
print(x)
end$ cat chapter8-2-loadfile.lua
1
2
3
4
5f = loadfile("foo.lua")
print(foo)
f()
print(foo)
foo("ok")gk350a :[~]# lua chapter8-2-loadfile.lua
1
2
3nil
function: 0xd6bcc0
ok
Chapter8.2 Code (如何載入C定義的lua library )
package.loadlib (libname, funcname)
Dynamically links the host program with the C library libname.
funcname must follow the protocol (see lua_CFunction)$ cat chapter8-2-loadlib.lua
1
2local path = "/usr/local/lib/lua/5.1/socket/core.so"
local f = package.loadlib(path,"luaopen_socket")
Chapter8.3 Error (如何取得程式的錯誤訊息)
通過error()函數傳入錯誤訊息
-
- Terminates the last protected function called and returns message as the error message. Function error never returns.
- Usually, error adds some information about the error position at the beginning of the message
- With level 1 (the default), the error position is where the error function was called
- Level 2 points the error to where the function that called error was called
$ cat chapter8-3-err.lua
1
2
3print "enter a number:"
n = io.read("*number")
if not n then error("invaild input") endxx :[~]# lua chapter8-3-err.lua
1
2
3
4
5
6
7
8
9
10enter a number:
dd
lua: chapter8-3-err.lua:3: invaild input
stack traceback:
[C]: in function 'error'
chapter8-3-err.lua:3: in main chunk
[C]: ?
gk350a :[~]# lua chapter8-3-err.lua
enter a number:
10
使用assert()功能來實現
assert (v [, message])
Issues an error when the value of its argument v is false (i.e., nil or false); otherwise, returns all its arguments.
message is an error message; when absent, it defaults to “assertion failed!”$ cat chapter8-3-err2.lua
1
2print "enter a number:"
n = assert(io.read("*nubmer"),"invaild input")
Chapter8-4 Error Handling and Exceptions
若需要lua中處理錯誤,則必需使用pcall函數來包裝要執行的代碼
pcall (f, arg1, ···)
Calls function f with the given arguments in protected mode.$ cat chapter8-4-pcall.lua
1
2
3
4
5cat chapter8-4-pcall.lua
local status,err = pcall(function () error({code=121}) end)
print(status,err.code)
local status,err = pcall(function () error("my error") end)
print(status,err)gk350a :[~]# lua chapter8-4-pcall.lua
1
2false 121
false chapter8-4-pcall.lua:3: my error
Chapter9 Coroutines (協同程序)
- A coroutine is similar to a thread (in the sense of multithreading)
- it is a line of execution, with its own stack, its own local variables, and its own instruction pointer;
- but sharing global variables and mostly anything else with other coroutines
- 多thead,是指同時多個程序一起跑
- 但coroutine,主要強調在多個thead中如何協同處理
Coroutine Manipulation
- 2.11 – Coroutines
- Lua supports coroutines, also called collaborative multithreading.
- A coroutine in Lua represents an independent thread of execution
func | note |
---|---|
coroutine.create | create a coroutine , it does not start the coroutine execution. |
coroutine.resume | passing as its first argument a thread, the coroutine starts its execution |
A coroutine can terminate its execution in two ways:
normally, when its main function returns (coroutine.resume returns true)
and abnormally5.2 – Coroutine Manipulation
The operations related to coroutines comprise a sub-library of the basic library and come inside the table coroutine.coroutine有下例狀態
- suspended
coroutine.create之後則為suspened - running
coroutine.resume之後則為running,若程式跳完離開則變成dead - dead
- normal
- suspended
coroutine.yield()會讓一個運行中的coroutine變成suspended狀態(即此時,程式停止)
$cat chapter9-yield.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16co = coroutine.create(function ()
for i=1,5 do
print("co",i)
coroutine.yield()
end
end)
coroutine.resume(co)
print("t1",coroutine.status(co))
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
coroutine.resume(co)
print("t2",coroutine.status(co))
coroutine.resume(co)xx:[~]# lua chapter9-yield.lua
1
2
3
4
5
6
7co 1
t1 suspended
co 2
co 3
co 4
co 5
t2 dead
通過resume-yield交換數據
$cat chapter9-2-data.lua
1
2
3
4
5
6co = coroutine.create( function (a,b,c)
print("co",a,b,c)
coroutine.yield(a+10,b+10,c+10)
end)
print(coroutine.resume(co,1,2,3))xx:[~]# lua chapter9-2-data.lua
1
2co 1 2 3
true 11 12 13
chapter9-2 producer-consumer problem
- 由coroutine.yield(x)回傳值x
- 此處為consumer-driver design
- 由consumer啟動
- 當consumber需要新值時,喚醒producer
- producer產生1個新的值,停止運行,等待consumer
$ cat chapter9-2-pipe.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22local producer
function receive()
local status, value = coroutine.resume(producer)
return value
end
function send(x)
coroutine.yield(x)
end
producer = coroutine.create(
function()
while true do
local x = io.read()
send(x)
end
end
)
print(receive())xx:[~]# lua chapter9-2-pipe.lua
1
2test
test
chapter 9-2 filter
- filter example
- 由filter來處理過程的資料
- 決定是否打用producer資料
- 是否將傳給consumer資料做格式轉換
$cat chapter9-2-filter.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39function receive (prod)
local status, value = coroutine.resume(prod)
return value
end
function send(x)
coroutine.yield(x)
end
function producer(x)
return coroutine.create(function ()
while true do
print("producer:")
local x = io.read()
send(x)
end
end)
end
function filter (prod)
return coroutine.create( function()
for line = 1, math.huge do
local x = receive (prod)
x = string.format("filter: %5d %s",line,x)
send(x)
end
end)
end
function consumer (prod)
while true do
local x = receive(prod)
io.write("cosumer:",x,"\n");
end
end
p = producer()
f = filter(p)
consumer(f)xxx :[~]# lua chapter9-2-filter.lua
1
2
3
4
5
6
7
8
9
10producer:
test11
cosumer:filter: 1 test11
producer:
aabb
cosumer:filter: 2 aabb
producer:
ccdd
cosumer:filter: 3 ccdd
producer:
Chapter 11 Data Structures
- all structure that other language offer
- arrays, records, lists, queues, sets
Chapter 11-1 Arrays
注意lua內部library的array皆為1開始
$cat chapter11-1-array.lua
1
2
3
4
5a = {}
for j=1, 1000 do
a[j] = 0
end
print(#a)gk350a :[~]# lua chapter11-1-array.lua
1
1000
也可以建立非零開始的index
- $cat chapter11-1-array2.lua
1
2
3
4a = {}
for i=-5, 5 do
a[i] = 0
end
Chapter 11-2 matrix(矩陣)
$cat chapter11-2-matrix.lua
1
2
3
4
5
6
7
8
9
10
11
12mt = {}
N = 3
M = 4
for i=1,N do
mt [i] = {}
for j=1,M do
mt[i][j] = 0
end
end
print(#mt)
print(#mt[1])xx :[~]# lua chapter11-2-matrix.lua
1
23
4
Chapter 11-4 Queues
- 由List.New初始化變數
first: 指向list頭
last: 指向list尾 - pushfist: 由first新增
- popfist: 由first取出
- pushlast: 由last新增
- poplast: 由last取出
$cat chapter11-4-queues.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34List = {}
function List.new ()
return {first = 0, last = -1}
end
function List.pushfirst(list, value)
local first = list.first - 1
list.first = first
list[first] = value
end
function List.pushlast (list, value)
local last = list.last + 1
list.last = last
list[last] = value
end
function List.popfirst (list)
local first = list.first
if first > list.last then error ("list is empty") end
local value = list[first]
list[first]=nil
list.first = first +1
return value
end
function List.poplast (list)
local last = list.last
if list.first > last then error("list is empty") end
local value = list[last]
list[last] = nil
list.last = last -1
return value
endtest code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17tt = {}
tt = List.new()
print(tt.first,tt.last)
List.pushfirst(tt,"11")
print("pushfirst 11",tt.first,tt.last)
List.pushfirst(tt,"21")
print("pushfirst 21",tt.first,tt.last)
List.pushfirst(tt,"31")
print("pushfirst 31",tt.first,tt.last)
print(tt[-1],tt[-2],tt[-3])
print(tt[-2])
print(tt[-3])
print("poplast value:",List.poplast(tt))
print("poplast",tt.first,tt.last)
print(tt[-1],tt[-2],tt[-3])
print(tt[-2])
print(tt[-3])xx:[~]# lua chapter11-4-queues.lua
1
2
3
4
5
6
7
8
9
10
11
120 -1
pushfirst 11 -1 -1
pushfirst 21 -2 -1
pushfirst 31 -3 -1
11 21 31
21
31
poplast value: 11
poplast -3 -2
nil 21 31
21
31
PARTIII; The Standard Library (待增加)
PARTIV; The C API (待增加)
其它
pairs及ipairs差異
pairs:依table內的順序一個一個找出來
會找到全部1
2
3
4
5
6
7
8
9a={[1]=11,[2]=22,[5]=55,["erwin"]=90, ["peter"]=92}
for i,v in pairs(a) do print(i,v) end
xx :[/tmp/tt]# lua t1.lua
2 22
1 11
p 92
5 55
e 90ipairs
pairs進階的找法,只依1,2,依順找,當沒有找到則離開1
2
3
4
5
6
7a={[1]=11,[2]=22,[5]=55,["erwin"]=90, ["peter"]=92}
for i,v in ipairs(a) do print(i,v) end
xx :[/tmp/tt]# lua t1.lua
1 11
2 22