1、基本知識ubuntu
1.第一個程序:數組
print("hello lua");函數
在交互模式下直接運行:oop
> print("hello lua")ui
hello lua --輸出this
保存在文件中運行:lua
$ lua hello.luaspa
hello lua --輸出命令行
2.chunks:orm
* 定義:trunks指運行的語句塊,一個文件,一個函數或是運行模式下每行語句、語句組合都是trunks;
* 語句之間的分割府(";")無關緊要,爲了可看性可維護性通常加「;」分割。
* 交互模式運行trunks:
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
>
a)交互模式鍵入的每行語句當即執行,不是完整的trunks時提示符爲「>>」提示繼續輸入直至語句完整,交互模式可鍵入文件結束符(Ctrl-D in Unix, Ctrl-Z in DOS/Windows),或是調用OS庫的os.exit()退出;
b)經過指定參數運行lua的一系列trunks,如一個文件a.lua有語句x = 1,文件b.lua有語句print(x),則在命令行調用>lua -la -lb 則輸出「1」。此命令首先運行a,再運行b(-l命令會調用require),使用-i選項運行完trunks語句後進入交互模式;
c)使用dofile加載外部trunk。如:
文件:
ubuntu$ cat ext.lua
function ext_trunk()
print("external trunks")
end
運行:
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> dofile("ext.lua")
> ext_trunk()
external trunks
>
* 全局變量不須要聲明,給出一個變量賦值後即建立變量。未初始化的全局變量值爲nil,刪除變量只需把值設置成nil:
print(b) --> nil
b = 10
print(b) --> 10
* 詞法約定:
a)標識符:字母或者下劃線開頭的字母、下劃線、數字序列(因爲lua保留子也是下劃線開頭因此最好不要使用下劃線開頭標識符);
b)保留字(lua大小寫敏感):
and break do else elseif end false for function if in local nil not or repeat return then true until while
c)lua註釋:單行註釋用「--」,多行註釋用:--[[ --]];
* 命令行方式:lua [options] [script [args]]
a)-e :將命令直接傳入(如:lua -e "print(math.sin(12))" --> -0.53657291800043);
b)-l:加載一個文件;
c)-i:進入交互模式;
d)經過_PROMPT內置變量存放交互模式的提示符
dht$lua -i -e "_PROMPT='mylua>'"
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
mylua>_PROMPT="hh>"
hh>
e)lua在運行參數以前會查找環境變量LUA_INIT的值,加載指定文件或代碼(實驗);
f)全局變量arg存放Lua命令行參數。
2、類型與值
1.lua有 八個基本類型:nil、boolean、number、string、userdata、function、thread和table。
a)可經過type函數獲取變量或值的類型字符串。如:
print(type("Hello lua")) --> string
print(type(10.4*3)) --> number
print(type(print)) --> function
b)變量沒有預約義類型,每一個變量可設置成任意一種類型,函數也能夠像變量同樣使用.如:
print(type(a)) --> nil
a = 10
print(type(a)) --> number
a = "a string!!"
print(type(a)) --> string
a = print
print(type(a)) --> function
2. nil:特殊類型,只有一個值nil,全局變量賦值之前值爲nil,刪除一個全局變量只需把變量賦值爲nil;
3. boolean:只有true和false兩個值,在控制語句中除了false和nil爲假,其他值都是真,如0和空串都是真;
4. number:表示實數,lua沒有整數;
5. string:字符序列,lua爲8位字節,字符串能夠包含任何數值字符
a)string進行自動內存分配和釋放;
b)lua支持的轉義序列列表:
\a bell
\b back space -- 後退
\f form feed -- 換頁
\n newline -- 換行
\r carriage return -- 回車
\t horizontal tab -- 製表
\v vertical tab
\\ backslash -- "\"
\" double quote -- 雙引號
\' single quote -- 單引號
\[ left square bracket -- 左中括號
\] right square bracket -- 右中括號
c)字符串中還能夠用\ddd表示字母,如:"alo\n123\""和'\97lo\10\04923"'是相同的
> print("alo\n123\"")
alo123"
> print('\97lo\10\04923"')
alo123"
>
d)用[[...]]表示字符串,能夠包含多行,第一個字符是換行會被自動忽略。如:
> page = [[
>> <HTML>
>> <TITLE> An HTML Page</TITLE>
>> "this is a string'
>> </HTML>
>> ]]
> print(page)
<HTML>
<TITLE> An HTML Page</TITLE>
"this is a string'
</HTML>
>
e)lua會自動在string和numbers之間自動進行類型轉換:
> print("10" + 1)
11
> print("10 + 1")
10 + 1
> print("-10" * "2")
-20
> print("hello" + 1) //出錯hello不能轉爲數字
stdin:1: attempt to perform arithmetic on a string value
stack traceback:
stdin:1:
in main chunk
[C]: ?
> print(10 .. 20)
1020
> print(tostring(10) == "10")
true
> print(10 .. "" == "10")
true
> print(10 == "10") //雖然能夠互相轉換,但類型不一樣並不相等
false
>
6. function:函數也是一個類型,能夠存儲在變量中,能夠做爲函數參數,返回值。
7. userdata和thread後面介紹。
3、表達式
1. 算術運算符:
* 二元運算符:+ - * / ^(加減乘除冪)
* 一元運算符:- (減)
* 算術運算符操做數都是實數
2. 關係運算符:< > <= >= == ~=
* 倆值類型不一樣,lua認爲二者不一樣,nil 只和本身相等:
> print(false == nil) --false和nil不相等
false
> print(x == nil)
true
>
* lua經過比較引用比較tables、userdata、functions:
> a = {}; a.x = 1; a.y = 0
> b = {}; b.x = 1; b.y = 0
> c = a
> print(a == c) --a和c互爲引用
true
> print(a == b) --a和b的值徹底相同,可是是不一樣對象
false
>
* lua比較數字按照傳統數字大小,比較字符串按照字母順序進行比較。混合比較數字和字符串會報錯:
> print(2 < 15)
true
> print("2" < "15") --字符串比較字母順序
false
> print("0" == 0) --類型不一樣
false
> print(2 < "15") --字符串和數字不能混合比較
stdin:1: attempt to compare number with string
stack traceback:
stdin:1: in main chunk
[C]: ?
>
3. 邏輯運算符:and or not
* 邏輯運算符認爲nil和false爲假,其他爲真:
* and和or運算結果不是true或false:
a) a and b:若是a爲false則返回a,不然返回b
> a = nil; b = 1
> print(a and b)
nil
> a = 1; b = 2
> print(a and b)
2
>
b) a or b:若是a爲true返回a,不然返回b
> a = nil; b = 1
> print(a or b)
1
> a = 1; b = 2
> print(a or b)
1
>
c) and的優先級比or高
d) C語言中的a ? b : c 至關於nil中的(a and b) or c
* not只返回true或者false
> print(not nil)
true
> print(not false)
true
> print(not 0)
false
4. 鏈接運算符:..(兩點),鏈接倆字符串,若是操做數爲數字,則會轉爲字符串:
> print("hello " .. "lua")
hello lua
> print(0 .. 1)
01
>
5. 優先級(從高到低)
^
not - (unary)
* /
+ -
..
< > <= >= ~= ==
and
or
6. 表的構造:
* 最簡單的構造函數:{} ,用來構造一個空表;
* 初始化一個數組(數組下標從1開始,數組元素能夠是任何類型):
> arr = {"str", 10, math.sin(10)} --實際初始化的模型是這樣的:arr = {[1] = "str", [2] = 10, [3] = math.sin(10)}
> print(arr[1]) --類型爲字符串
str
> print(arr[2]) --類型爲數字
10
> print(arr[3]) --類型爲函數表達式
-0.54402111088937
* 初始化一個表:tbl = {x=1, y=2} 與 tbl = {}; tbl.x = 1; tbl.y = 2 和tbl = {['x'] = 1, ['y'] = 2}等價;
* 無論用何種方式建table,均可以向表中添加、刪除任何類型的域,構造函數僅影響初始化
* 用table構造一個list:
words = {"A", "B", "C", "D"}
list = nil;
for k, v in pairs(words) do
list = {next=list, value=v}
end
l = list
while l do
print(l.value)
l = l.next
end
結果爲:D B C A
* 混合使用列表和記錄進行初始化:
polyline = {color="blue", {x=0, y=0}, {x=-10, y=0}}
print(polyline[2].x) --> -10
結果爲:-10
* table下標通常不從0開始,不少標準庫不支持。構造函數中的域能夠用逗號(,)隔開,也能夠用分號(;)隔開
4、基本語法
Lua 傳統語句:賦值語句、控制結構語句、函數調用等,同時也支持非傳統的多變量賦值、局部變量聲明。
1. 賦值語句
* a = "hello " .. "lua" --單個變量賦值
* a, b = 10, 20 ---兩個變量賦值至關於 b = 20; a = 10(先右邊賦值再左邊賦值)
* x, y = y, x --根據先右邊賦值再左邊賦值的特性,此代碼能夠交換兩個變量
* 當變量個數>值個數時多餘變量值爲nil:
a, b = 10; print(a,b); -- 結果爲10 nil
* 變量個數<值個數時多餘的值被忽略
a, b = 10, 20, 30; print(a,b); ---結果爲10 20
* 注意:兩個變量賦值按照先右後左,可是多個變量的狀況下必須從左到右依次賦值,函數返回無論多少個值都是從左到右依次賦值。
2. 局部變量與代碼塊
* 局部變量添加local來聲明,局部變量只在聲明局部變量的代碼塊內有效
* 在交互模式下局部變量的做用域可能和想的會有所不一樣,由於一行執行是個完整的chunk
> local i = 1
> print(i)
nil
>
* 利用do ... end能夠更好的定義語句塊,爲一個chunk劃分界限。do ... end至關於C中的{...}
> do
>> local i = 1
>> print(i)
>> end
1
>
3. 控制結構語句
*if語句的三種形式:
if conditions then ---1
then-part
end;
if conditions then ---2
then-part
else
else-part
end;
if conditions then ---3
then-part
elseif conditions then
elseif-part
.. --->多個 elseif
else
else-part
end;
*while 語句
while condition do
statements;
end;
*repeat-until語句
repeat
statements;
until conditions;
*for語句的兩種
a) 數值for循環
for var=exp1,exp2,exp3 do loop-part end
b) 範型 for循環
for i,v in ipairs(a) do print(v) end
4. break和return語句
* break語句用於退出循環:for repeat while --循環外不可以使用
* return 用來返回函數結果
* break和return只能在block的前一句,即在end,else,until以前
* 一般能夠在代碼中插入 do return end的方式使得return能夠出如今代碼塊中間。