官术网_书友最值得收藏!

3.6 運算

Lua里的運算有算術運算、關系運算、邏輯運算、字符串運算等。

3.6.1 算術運算

Lua的算術運算包括基本的加減乘除,取模運算使用“%”,冪運算使用“^”:

print(1 + 1, ", ", 5-3)         -- 加減法運算,輸出2,2
print(2 * 4, ", ", 1 / 3)         -- 乘除法運算,輸出8,0.33333333333333
print(5 % 2, ", ", 3 ^ 3)         -- 取模和冪運算,輸出1,27

算術運算時可以混用字符串類型,Lua會自動把字符串轉換為數字,但如果含有非數字字符無法轉換就會出錯,所以最好不要混用。

Lua不提供其他語言里的遞增和遞減操作符(可能的原因是“--”已經被用作注釋語法了),遞增遞減操作只能使用標準的賦值形式,例如:

count = 10                        -- 一個整數變量
count = count + 1                -- 加1后賦值,相當于++count

3.6.2 關系運算

Lua的關系運算符與其他語言基本相同,如“>”“>=”“<”“<=”“==”,但不等比較使用的是“~=”,需要特別注意:

print(3.14 > 2.718)              -- 大于關系
print(1/3 == 2/6)                -- 等于關系
print('10' ~= 10)                -- 不等關系,注意運算符是“~=”,不是“! =”

在執行大于或小于比較操作時Lua會檢查變量的類型,如果類型不同就會出錯,例如:

print(1 > "0")                    -- 報錯,無法執行

但“==”和“~=”的行為則不同,如果類型不同會直接返回false。

實際開發中比較常見的情況是比較字符串形式的數字,為了避免發生意外,必須用函數tonumber()/tostring()顯式轉換數字或字符串后再做比較運算,例如:

print(1 > tonumber('0'))          -- 大于比較,使用tonumber()后正常
print('10' == 10)                 -- 比較的類型不同,結果為false
print(tonumber('10') == 10)       -- 等于關系,結果為true

3.6.3 邏輯運算

Lua的邏輯運算符有and、or和not三個,但運算規則有些特殊:

■ nil和false認為是假,其他都是真,包括數字0;

■ x and y,如果x是真,返回y,否則返回x;

■ x or y,與and操作正好相反,如果x是真,返回x,否則返回y;

■ not x,只返回true/false,對x取反。

對于C程序員來說第一條規則需要特別注意,因為在C語言里0是假,和false等價,但在Lua語言里0是真,nil和false等價,在書寫條件判斷代碼時必須小心。

下面的代碼示范了Lua里的邏輯運算:

print(0 and 'abc')                --0是真,所以返回字符串’abc'
print(x or 100)                   -- x是全局變量,值是nil,返回100
print(not x)                      -- x是全局變量,值是nil,返回true

利用Lua邏輯運算的特性可以實現非常靈活的賦值功能:

local x = count or 100           -- 為x賦初值,count不存在則默認值是100
local y = a and b or c           -- 相當于a? b:c,由a的真假決定賦值b或c

3.6.4 字符串運算

Lua對字符串連接操作提供了一個特別的運算符“..”:

print('hello'..' '..'world')    -- 連接多個字符串

連接運算還可以自動把數字轉換為字符串,無須顯式調用tostring()函數:

print("room number is " .. 313) -- 可以直接連接數字,無須轉換

雖然Lua可以高效地處理字符串,但字符串連接操作應當盡量少用,因為每一次字符串連接就會創建一個新的字符串對象,如果多次操作超長字符串(例如幾十MB的大塊數據)就可能會導致LuaVM內存耗盡,發生錯誤。

計算字符串的長度可以用另一個特別的運算符“#”:

print(#'openresty')              -- 計算字符串長度,輸出9

字符串的關系運算基于字符序(例如最常用的ASCII碼表)逐個檢查,但相等比較是直接計算內部保存的散列值,速度很快(見3.4節):

print("a" < "b")                 -- 結果為true,字符序檢查
print("zero" > "0")              -- 結果為true,字符序檢查
print("abc" == "abc")            -- 結果為true,比較的是內部散列值

3.6.5 注意事項

在運算時我們需要注意操作數是nil的情形,很多時候對nil運算都會導致錯誤,例如:

x = nil                           -- x的值是nil
print(1 + x)                      -- 出錯,無法執行加法運算
print("msg is "..x)               -- 出錯,無法執行連接運算

如果一個變量可能是nil,最好使用or運算給它一個默認值:

print(1 + (x or 2))              -- 正常,x不存在則使用2執行加法運算
print("msg is ".. (x or "-"))    -- 正常,x不存在則使用"-"執行連接運算
主站蜘蛛池模板: 章丘市| 龙口市| 临颍县| 泰安市| 泾阳县| 长沙市| 宜宾市| 西青区| 揭东县| 嘉义市| 扎兰屯市| 贵港市| 崇信县| 阳泉市| 聊城市| 中宁县| 兴和县| 原平市| 柏乡县| 凌海市| 磴口县| 荥经县| 华坪县| 汶川县| 林口县| 莱芜市| 青冈县| 慈溪市| 塘沽区| 临湘市| 石景山区| 措美县| 章丘市| 自贡市| 图们市| 麻阳| 神农架林区| 扎鲁特旗| 梁平县| 灯塔市| 台州市|