redis學習(八) Lua語法
Lua語法
資料型別
Lua是一個動態型別語言,一個變數可以儲存任何型別的值。編寫redis指令碼會用到的型別
型別名 | 取值 |
空(nil) | 空型別只包含一個值,即nil。nil表示空,所有沒有賦值的變數或表的欄位都是nil |
布林(boolean) | 布林型別包含true和false |
數字(number) | 整數和浮點數都是使用數字型別儲存,如1、0.23、3.5e20等 |
字串(string) | 字串型別可以儲存字串,且與redis的鍵值一樣都是二進位制安全的。字串可以使用單引號或雙引號表示,兩個符號是相同的,比如'a'和"a",字串中可以包含轉義字元,如\n,\r等 |
表(table) | 表型別是Lua語言中唯一的資料結構,既可以當陣列有可以當字典,十分靈活 |
函式(function) | 函式在Lua中是一等值(first-class-value),可以儲存在變數中、作為函式的引數或返回結果 |
變數
Lua的變數分為全域性變數和區域性變數。全域性變數無需宣告就可以直接使用,預設為nil
a=1 --為全域性變數賦值
print(b) --無需宣告即可使用,預設是nil
a = nil --刪除全域性變數a的方法是將其賦值為nil。全域性變數沒有宣告和未宣告之分,只有非nil和nil區別
在redis指令碼中不能使用全域性變數,只允許使用區域性變數以防止指令碼之間的相互影響,宣告區域性變數的方法為local變數名
local c --宣告一個區域性變數c,預設值是nil
local d =1 --宣告區域性變數並賦值1
local e,f --同時宣告多個區域性變數
變數名必須是非數字開頭,只能包含字母、數字和下劃線,區分大小寫。變數名不能和Lua的保留關鍵字相同,保留關鍵字如下:
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while
區域性變數的作用域為從宣告開始到所在層的語句塊末尾,比如
local x =10
if true then
local x = x+1
print(x)
do
local x = x+1
print(x)
end
print(x)
end
print(x)
依次輸出:
11 12 11 10
註釋
單行註釋以--開始,到行尾結束,一般習慣在--後面跟上一個空格
多行註釋以--[[開始,到]]結束
賦值
Lua支援多重賦值,比如:
local a,b = 1,2
local c,d = 1,2,2 -- c的值是1,d的值是2,3被捨棄了
local e,f = 1 -- e的值是1,f的值是nil
在執行多重賦值是,lua會先計算所有表示式的值,比如
local a = {1,2,3}
local i = 1
i,a[i] = i+1,5 變為 i,a[1] = 2,5 賦值後i為2, a則為{5,2,3}
操作符
Lua有以下5類操作符
1> 數學操作符。 + - * / %(取模) - (取負) 冪運算子 ^
print('1'+1) -- 2 數學操作符的運算元如果是字串會自動轉換為數字
2> 比較操作符 結果一定是boolean
3>邏輯操作符
操作符 | 說明 |
not | 根據運算元的真和假相應地返回false和true |
and | a and b 中如果a為真則返回b,否則返回a |
or | a or b 如果 a 是true 則返回 a,否則返回b |
只要運算元不是nil或false,邏輯操作符就認為操作符是真,否則是假。特別需要注意的是即使是0或者空字串也被當做是真
print(1 and 5) -- 5
print(1 or 5) -- 1
print(not 0) -- false
print('' or 1) -- ''
Lua的邏輯操作符支援短路,也就是說對於false and foo() ,Lua不會去呼叫foo(),or 操作符類似
4> 連線操作符。 連線操作符只有一個 : ..,用來連線兩個字串,比如
print('hello'..''..'world') -- hello world
連線操作符會自動把數字型別轉為字串型別
5> 取長度操作符。 # 例如 print(#'hello') -- 5
運算子的優先順序(優先順序依次降低)
^
not # - (一元)
* / %
+ -
..
< > <= >= ~= ==
and
or
if語句
Lua的if語句格式如下:
if 條件表示式 then
語句塊
elseif 條件表示式 then
語句塊
else 語句塊
end
note: 在Lua中只有nil和false才是假,其餘值都是真,包括空字串和0,都是認為是真的。這是一點容易出錯的地方。比如說:
if redis.call('exists','key') then
exists = true
else
exists = false
end
這個exists返回的就是1或0,一定返回的是真,就有問題了,改為 if redis.call('exists','key') == 1 才正確
Lua與javascript每個語句都可以;結尾,都是省略的,當然也可以寫在一行,最好分行寫
迴圈語句
Lua支援 while,repeat 和 for迴圈語句
while 語句的形式為:
while 條件表示式 do
語句塊
end
repeat語句的形式為:
repeat 語句塊 until 條件表示式
for語句有兩種形式,一種是數字形式:
for 變數 = 初值 ,終值,步長 do 語句塊 end
其中步長可以省略,預設步長是1,比如使用for迴圈計算1~100的和
local sum = 0
for i=1 ,100 do sum = sum+1 end
提示: for語句中的迴圈變數是區域性變數,作用域為for迴圈體內,雖然沒有使用local宣告,但不是全域性變數
for 語句的通用形式為: for 變數1,變數2,....變數n in 迭代器 do 語句塊 end
表型別
表是Lua中唯一的資料結構,可以理解為關聯陣列,任何型別的值(除了空型別)都可以作為表的索引
表的定義方式:
a = {} -- 將變數a賦值為一個空表
a['field'] = 'value'
print(a.field); --列印內容為'value',a.field是a['field']的語法糖
或者定義:
people = {name = 'zhouy',age = 29 } print {people.name} --列印內容為Bob
當索引為整數的時候表和傳統的陣列一樣,例如:
a = {} a[1] = 'zhouy' a[2] = 'Jeff' 可以寫成這樣: a = { 'zhouy','jeff'} print{a[1]}
note: Lua 約定陣列的索引是從1開始的,而不是0
表的遍歷方式:
1. 通用形式的for語句遍歷陣列
for index,value in ipairs(a) do
print(index)
print(value)
end
ipairs是lua內建的函式,實現類似迭代器的功能
2.使用數字形式的for語句遍歷陣列
for i =1 ,#a do
print(i)
print(a[i])
end
#a作用是獲取表a的長度
3. 迭代器pairs用來遍歷非陣列的表值。
people = {name = 'zhouy',age = 29}
for index, value in pairs(people) do
print (index)
print(value)
end
pairs和ipairs的區別是前者會遍歷所有值不為nil的索引,而後者只會從索引1開始遞增遍歷到最後一個值不為nil的整數索引
函式
函式的定義為:
function (引數列表)
函式體
end
可以將其賦值為一個區域性變數,比如
local square = function(num ) return num*num end
如果沒有引數,括號也不能省略。Lua還提供了一個語法糖來簡化函式的定義,比如
local function square (num)
return num*num
end
這段程式碼會轉換為:
local square
square = function (num) return num*num
end
如果實參的個數小於形參的個數,則沒有品牌到的形參的值為nil.相對應的,如果實參的個數大於形參的個數,則多出來的實參
會被忽略。如果希望捕獲多出的實參,可以讓最後一個形參為...。比如,希望傳入若干個引數計算這些數的平方
local function square (...)
local argn = {...}
for i=1,#argv do
argv[i] = argv [i] * argv[i]
end
unpack函式用來返回表中的元素
標準庫
String庫
1>獲取字串長度 string.len(string)
2>轉換大小寫 string.lower string.upper
3>獲取子字串 string.sub(string,start,end) 索引從1開始,-1代表最後一個元素。end引數如果省略,預設是-1
Table庫
1> 將陣列轉為字串
table.concat(table[,sep[, i[, j ] ] ] );
舉個例子
print (table.concat({1,2,2},',',2); ---> '1,2,22'
2>向陣列中插入元素
table.insert(table,[post,] value) ;向 指定索引位置pos插入元素value,並將後面的元素順序後移,預設pos的值是陣列長度加1,即在陣列尾部插入,注意索引從1開始的
3> 從陣列中彈出一個元素
table.remove(table [,pos]) 從指定索引位置刪除元素,並將後面的元素前移,返回刪除元素的值
其他需要了解的:
cjson.encode :序列化為字串
cjson.decode :將序列化後的字串還原為表
cmsgpack.unpack 將序列化後的字串還原為表
相關文章
- lua學習之入門(二)----基礎語法1
- lua~基本語法
- lua學習: lua及函數語言程式設計語言函數程式設計
- Lua遊戲開發(三)---Lua語言學習(上)遊戲開發
- redis原始碼學習之lua執行原理Redis原始碼
- Redis基礎知識(學習筆記21--Lua 指令碼語言)Redis筆記指令碼
- 【Redis 系列】redis 學習八,redis 持久化 RDB 和 AOFRedis持久化
- 熱更新語言--lua學習筆記筆記
- Redis基礎知識(學習筆記21--Lua 指令碼語言2)Redis筆記指令碼
- Redis學習筆記八:叢集模式Redis筆記模式
- Lua語法基礎教程(上篇)
- MarkDown語法學習
- C#與Lua語言學習對比一C#
- lua 學習總結
- Lua學習筆記筆記
- Redis與Lua及Redis-py應用LuaRedis
- Flutter Dart語法學習FlutterDart
- tensorflow語法學習
- Scala基本語法學習
- Java SE 語法學習Java
- redis 通用語法Redis
- Lucene學習總結之八:Lucene的查詢語法,JavaCC及QueryParser(1)Java
- Lua 學習筆記(上)筆記
- 學習Lua的意義
- 從sysbench中學習Lua
- Lua學習筆記(一)筆記
- Redis學習筆記(三)使用Lua指令碼實現分散式鎖Redis筆記指令碼分散式
- lua語法-程式塊(chunk)與註釋
- Presto 與 Hive 語法學習RESTHive
- SQL學習___03:DML語法SQL
- 學習Rust 基礎語法Rust
- PHP基本語法學習 [常量]PHP
- PHP基本語法學習 常量PHP
- Clojure語法學習-迴圈
- markdown基本語法的學習
- markdown學習(基礎語法)
- Redis - Lua 指令碼Redis指令碼
- 【Redis】Redis 學習Redis