Lua數據類型


【1】Lua數據類型

Lua語言共有8種基本類型

[1] nil    空。最簡單,有且僅有值nil,表示一個無效值(在條件表達式中相當於false)

[2] boolean  布爾。包含兩個值:false和true

[3] number   數字。double(雙精度)類型(默認類型可以修改 luaconf.h 里的定義)

[4] string   字符串。字符串由一對雙引號或單引號來表示

[5] function  函數。由C或Lua編寫的函數

[6] userdata  自定義類型。表示任意存儲在變量中的C數據結構

[7] thread   線程。表示執行的獨立線程,用於執行協同程序

[8] table   表。Lua中的表(table)其實是一個“關聯數組”(associative arrays),數組的索引可以是數字或者是字符串。

               在Lua里,table的創建是通過“構造表達式”來完成,最簡單構造表達式是{},用來創建一個空表。

【2】各種數據類型示例

(1)各種數據類型

1.1 打印各種數據類型

1 print(type("Good Good Study"))  --> string
2 print(type(12.34))              --> number
3 print(type(print))              --> function
4 print(type(type))               --> function
5 print(type(true))               --> boolean
6 print(type(nil))                --> nil
7 print(type(type(X)))            --> string

1.2 打印各種數據類型

1 print(type(a))    --> nil
2 a = 100
3 print(type(a))    --> number
4 a = "Day Day Up"
5 print(type(a))    --> string
6 a = print
7 print(type(a))    --> function
8 a(type(a))        --> function

1.3 待續

(2)nil

2.1 nil類型表示一種沒有任何有效值,它只有一個值nil。例如:打印一個沒有賦值的變量,結果為nil值。

1 print(type(X))                  --> nil

2.2 nil 作比較時應該加上雙引號:

1 print(type(X) == nil)           --> false
2 print(type(X) == "nil")         --> true

type(X) == nil結果為false,因為:

1 print(type(type(X)))            --> string

2.3 對於全局變量和table,nil還有一個“刪除”作用。如下示例:

 1 luaTable = {10, 20, 30, 40, 50}
 2 for k, v in pairs(luaTable) do
 3     print(k .. " - " .. v)
 4 end
 5 
 6 luaTable[2] = nil
 7 print("After set nil :: ")
 8 for k, v in pairs(luaTable) do
 9     print(k .. " - " .. v)
10 end
11 
12 --[[
13 1 - 10
14 2 - 20
15 3 - 30
16 4 - 40
17 5 - 50
18 After set nil ::
19 1 - 10
20 3 - 30
21 4 - 40
22 5 - 50
23 --]]

2.4 讀入行數據作為數組元素

 1 --[[讀入行 作為數組元素]]
 2 a = {}
 3 for i = 1, 5 do
 4 a[i] = io.read()
 5 end
 6 
 7 for i, v in pairs(a) do
 8     print(i .. " ---> " .. v)
 9 end
10 
11 print(a)
12 
13 --[[ 執行結果
14 10
15 11
16 12
17 13
18 14
19 1 ---> 10
20 2 ---> 11
21 3 ---> 12
22 4 ---> 13
23 5 ---> 14
24 ]]

2.5 待續

(3)boolean

3.1 lua語言中nil和false均是屬於假,true和其他任何東西都屬於真。

C++語言中0、NULL和false均是屬於假,true其他任何非空的東西都屬於真。

尤其注意:lua中0被視為真。

示例如下:

 1 print(0)              --> 0
 2 print(0 == false)     --> false
 3 
 4 b = 0;
 5 print(b == true)      --> false
 6 
 7 if(0 and b) then
 8     print("0 and b is true")  --> 0 and b is true
 9 else
10     print("0 and b id false")
11 end
12 
13 if(nil) then
14     print("nil is true")
15 else
16     print("nil is false")  --> nil is false
17 end
18 
19 print(nil)            --> nil
20 print(false == nil)   --> false
21 print(true == nil)    --> false
22 print(true == "nil")  --> false
23 print(false == "nil") --> false
24 print(false == "")    --> false
25 print(100 == 100)     --> true

3.2 待續 

(4)number

4.1 待續

(5)string

5.1 字符串由一對雙引號或單引號來表示:

1 string1 = "this is string1"
2 print(string1)    --> this is string1
3 
4 string2 = 'this is string2'
5 print(string2)    --> this is string2

5.2 除過以上兩種表示方式,還可以使用方括號“[[]]”來表示“一塊”字符串:

 1 html = [[
 2 <html>
 3 <head></head>
 4 <body>
 5     <a href="http://www.baidu.com/">百度首頁</a>
 6 </body>
 7 </html>
 8 ]]
 9 print(html)
10 
11 --執行結果:
12 --[[
13 <html>
14 <head></head>
15 <body>
16     <a href="http://www.baidu.com/">百度首頁</a>
17 </body>
18 </html>
19 --]]

5.3 在對一個數字字符串進行算術操作時,Lua會嘗試將這個數字字符串轉換為一個數字:

1 print("1" + 2)      --> 3
2 print("3" + "4")    --> 7
3 print("5 + 6")      --> 5 + 6
4 print("8" * "8")    --> 64
5 --print("nil" + 1)  --> syntax error

5.4 如上代碼中“nil”+ 1執行報錯了,字符串連接使用的是 ..,如下所示:

1 print("a"..'b'.."cdefg".." ".."hijk")  --> abcdefg hijk
2 print(112 .. 110 .. 119)               --> 112110119

5.5 使用 # 來計算字符串的長度,放在字符串前面。如下示例:

1 strLength = "www.baidu.com"
2 print(#strLength)          -- 13
3 print(#"www.baidu.com")    -- 13
4 print(#"www.bai\0du.com")  -- 14
5 print(#"www.bai\ndu.com")  -- 14

5.6 字符串函數的應用示例

  1 --1 大小寫轉換
  2 --[[
  3 string.upper(argument)
  4 string.lower(argument)
  5 ]]
  6 str = "abcdefghijklmnopqrstuvwxyz"
  7 STR = string.upper(str)
  8 str1 = string.lower(STR)
  9 print(str)                -- abcdefghijklmnopqrstuvwxyz
 10 print(string.upper(str))  -- ABCDEFGHIJKLMNOPQRSTUVWXYZ
 11 print(STR)                -- ABCDEFGHIJKLMNOPQRSTUVWXYZ
 12 print(str1)               -- abcdefghijklmnopqrstuvwxyz
 13 
 14 
 15 
 16 --2 在字符串中替換
 17 --[[
 18 string.gsub(main string, find string, replace string, num)
 19 main string 要替換的字符串
 20 find string 被替換的字符
 21 relace string 要替換的字符
 22 num 替換次數 備注:可以忽略,默認是全部替換
 23 ]]
 24 
 25 str2 = "aaaaaaa"
 26 print(string.gsub(str2, "a", "b", 3)) -- bbbaaaa    3
 27 print(string.gsub(str2, "a", "c"))    -- ccccccc    7
 28 
 29 
 30 
 31 --3 搜索指定字符串
 32 --[[
 33 在一個指定的目標字符串中搜索指定的內容(第三個參數為起始索引),返回其具體位置。不存在則返回nil。
 34 ]]
 35 str3 = "Welcome to Beijing"
 36 print(string.find(str3, "Beijing"))         -- 12 18
 37 
 38 local index = string.find(str3, "Beijing")
 39 print(index)                                -- 12
 40 
 41 print(string.find(str3, "Beijing", 12))     -- 12 18
 42 print(string.find(str3, "Beijing", 13))     -- nil
 43 
 44 --4 字符串反轉
 45 --[[
 46 string.reverse(argument)
 47 ]]
 48 str4 = "Welcome to xian."
 49 print(string.reverse(str4))  -- .naix ot emocleW
 50 
 51 
 52 --5 格式化字符串
 53 --[[返回一個類似於printf的格式化字符串
 54 string.format(...)
 55 ]]
 56 
 57 str5 = "the value is :: %d"
 58 print(string.format(str5, 10))   -- the value is :: 10
 59 
 60 
 61 --6 整型數值與字符相互轉換
 62 --[[將整型數字轉成字符並連接string.char(argument)
 63 將字符轉成整型數字值(可以指定某個字符,默認是第一個字符)
 64 ]]
 65 print(string.char(97, 98, 99, 100))   -- abcd
 66 str6 = "ABCDE"
 67 print(string.byte("ABCD", 4))   -- 68
 68 print(string.byte("ABCD"))      -- 65
 69 
 70 --7 計算字符串長度
 71 --[[
 72 string.len(argument)
 73 ]]
 74 print(string.len("abcde"))    -- 5
 75 
 76 
 77 --8 返回字符串string的n個拷貝
 78 --[[
 79 string.rep(string, n)
 80 ]]
 81 print(string.rep("abcde ", 3))  -- abcde abcde abcde
 82 
 83 --9 鏈接兩個字符串
 84 --[[
 85 ..
 86 ]]
 87 print("Welcome ".."to ".."Beijing") -- Welcome to Beijing
 88 
 89 
 90 --10 gmatch接口
 91 --[[string.gmatch(str, pattern)
 92 返回一個迭代器函數,每一次調用這個函數,返回一個在字符串str找到的下一個符合pattern描述的子串。如果參數pattern描述的字符串沒有找到,迭代函數返回nil
 93 ]]
 94 local str10_1 = "Hello World By Lua"
 95 for word in string.gmatch(str10_1, "%a+") do
 96     print(word)
 97 end
 98 
 99 --[[執行結果
100 Hello
101 World
102 By
103 Lua
104 ]]
105 
106 local str10_2 = "110abc119,def,120,ghij"
107 local ret_func_itor = string.gmatch(str10_2, "%d+")
108 
109 -- 查看func_itor類型
110 print("ret_func_itor is", ret_func_itor) -- func_itor is    function: 02D1DAC8
111 
112 -- 第一次調用函數func_itor
113 print("ret_func_itor ret is ", ret_func_itor()) -- ret_func_itor ret is     110
114 
115 -- 再次調用函數func_itor
116 print("ret_func_itor ret is ", ret_func_itor()) -- ret_func_itor ret is     119
117 
118 -- 再次調用函數func_itor
119 print("ret_func_itor ret is ", ret_func_itor()) -- ret_func_itor ret is     120
120 
121 -- 再次調用函數func_itor
122 print("ret_func_itor ret is ", ret_func_itor()) -- ret_func_itor ret is
123 
124 
125 -- 使用循環來打印
126 local str10_3 = "hello world by Lua"
127 local index = 1
128 print("\noutput capture using loop:")
129 for word in string.gmatch(str10_3, "%a+") do
130     print(index, word)
131     index = index + 1
132 end
133 
134 --[[執行結果
135 output capture using loop:
136 1    hello
137 2    world
138 3    by
139 4    Lua
140 ]]
141 
142 -- 查找屬性對
143 local str10_4 = "from=world, to=Lua, name=kaizen"
144 print("\noutput attr pair capture using loop:")
145 for k, v in string.gmatch(str10_4, "(%w+)=(%w+)") do
146     print(k, v)
147 end
148 
149 --[[執行結果
150 output attr pair capture using loop:
151 from    world
152 to    Lua
153 name    kaizen
154 ]]
155 
156 local str10_5 = "fadfasd,.;p[];'asd"
157 local func_numitor = string.gmatch(str10_5, "%d+")
158 local numret = func_numitor()
159 print("\nnumret ret is", numret)
160 
161 --[[執行結果
162 numret ret is    nil
163 ]]

5.7 可以通過數值來指定字符串中的字符

1 --[[可以通過數值來指定字符串中的字符。
2 數值以轉義序列“\<ddd>”給出,其中<ddd>是一個至多3個十進制數字組成的序列]]
3 
4 print("\97bcdefg\10hijklmn\49")
5 
6 --[[執行結果
7 abcdefg
8 hijklmn1
9 ]]

5.8 字符串格式化format函數

1 str = string.format("字符串:%s\n整數:%d\n小數:%f\n十六進制數:%X", "zhongguorenmin", 1, 1.23, 456)
2 print(str)
3 
4 --[[
5 字符串:zhongguorenmin
6 整數:1
7 小數:1.230000
8 十六進制數:1C8
9 ]]

5.9 待續

(6)function

6.1 在Lua中,函數可以存在變量里:

 1 function factorial1(n)
 2     if n == 0 then
 3         return 1
 4     else
 5         return n * factorial1(n - 1)
 6     end
 7 end
 8 
 9 print(factorial1(5))     --> 120
10 
11 factorial2 = factorial1
12 print(factorial2(5))     --> 120

6.2 function可以以匿名函數(anonymous function)的方式通過參數傳遞

 1 function testFun(tab, fun)
 2     for k, v in pairs(tab) do
 3         print(fun(k, v));
 4     end
 5 end
 6 
 7 
 8 tab = {key1 = "val1", key2 = "val2"};
 9 testFun(tab,
10 function(key, val) --匿名函數
11     return key .. " = " .. val;
12 end
13 );
14 --執行結果
15 --[[
16 key1 = val1
17 key2 = val2
18 --]]

6.3 待續

(7)userdata

7.1 待續

(8)thread

8.1 待續

(9)table

9.1 創建一個空表

1 --1.創建一個空表
2 local tab1 = {}

9.2 初始化表,且遍歷表

 1 --2.直接初始化表
 2 local tal2 = {"apple", "pear", "orange", "grape"}
 3 --遍歷表
 4 for k, v in pairs(tal2) do
 5     print("key", k, ": value", v)
 6 end
 7 
 8 --執行結果
 9 --[[
10 key    1    : value    apple
11 key    2    : value    pear
12 key    3    : value    orange
13 key    4    : value    grape
14 ]]

9.3 關聯數組,數組的索引可以是數字或字符串

 1 array = {}
 2 array["key"] = "value"
 3 key = 10;
 4 array[key] = 20
 5 array[key] = array[key] + 11;
 6 for k, v in pairs(array) do
 7     print(k .. " : " .. v)
 8 end
 9 
10 --執行結果
11 --[[
12 key : value
13 10 : 31
14 --]]
15 
16 ar = {}
17 for i = 1, 10 do
18     ar[i] = i
19 end
20 
21 ar["key"] = "val"
22 print(ar["key"])
23 print(ar["none"])
24 
25 for k, v in pairs(ar) do
26     print(k .. " : " .. v)
27 end
28 
29 --執行結果
30 --[[
31 val
32 nil
33 1 : 1
34 2 : 2
35 3 : 3
36 4 : 4
37 5 : 5
38 6 : 6
39 7 : 7
40 8 : 8
41 9 : 9
42 10 : 10
43 key : val
44 ]]

9.4 注意觀察以上幾個示例,Lua里表的初始索引一般以1開始。不同於其他語言把0作為數組的開始索引。

 1 local tbl = {"apple", "pear", "orange", "grape"}
 2 for key, val in pairs(tbl) do
 3     print("Key", key)
 4 end
 5 
 6 --執行結果
 7 --[[
 8 Key    1
 9 Key    2
10 Key    3
11 Key    4
12 ]]

9.5 表的值置為nil,表示移除引用。

 1 --當我們定義table a 並設置元素,然后將 a 賦值給 b,則 a 與 b 都指向同一個內存。
 2 --如果 a 設置為 nil ,則 b 同樣能訪問 table 的元素。
 3 --如果沒有指定的變量指向a,Lua的垃圾回收機制會清理相對應的內存。
 4 
 5 -- 簡單的 table
 6 mytable = {}
 7 print("mytable 的類型是 ", type(mytable))
 8 
 9 mytable[1] =  "Lua"
10 mytable["wow"] = "修改前"
11 print("mytable 索引為 1 的元素是 ", mytable[1])
12 print("mytable 索引為 wow 的元素是 ", mytable["wow"])
13 
14 -- alternatetable和mytable的是指同一個 table
15 alternatetable = mytable
16 print("alternatetable 索引為 1 的元素是 ", alternatetable[1])
17 print("mytable 索引為 wow 的元素是 ", alternatetable["wow"])
18 
19 alternatetable["wow"] = "修改后"
20 print("mytable 索引為 wow 的元素是 ", mytable["wow"])
21 
22 -- 釋放變量
23 mytable = nil
24 print("mytable 是 ", mytable)
25 --print("mytable[1]", mytable[1]) --> syntax error
26 
27 -- alternatetable 仍然可以訪問
28 print("alternatetable 索引為 wow 的元素是 ", alternatetable["wow"])
29 
30 alternatetable = nil
31 print("alternatetable 是 ", alternatetable)
32 
33 --執行結果
34 --[[
35 mytable 的類型是     table
36 mytable 索引為 1 的元素是     Lua
37 mytable 索引為 wow 的元素是     修改前
38 alternatetable 索引為 1 的元素是     Lua
39 mytable 索引為 wow 的元素是     修改前
40 mytable 索引為 wow 的元素是     修改后
41 mytable 是     nil
42 alternatetable 索引為 wow 的元素是     修改后
43 alternatetable 是     nil
44 ]]

9.6 表操作

[1] concat方法

 1 --table.concat (table [, sep [, start [, end]]]):
 2 --concat是concatenate(連鎖, 連接)的縮寫.
 3 --table.concat()函數列出參數中指定table的數組部分從start位置到end位置的所有元素, 元素間以指定的分隔符(sep)隔開
 4 
 5 fruits = {"banana","orange","apple"}
 6 -- 返回 table 連接后的字符串
 7 print("連接后的字符串 ",table.concat(fruits))
 8 
 9 -- 指定連接字符
10 print("連接后的字符串 ",table.concat(fruits, ", "))
11 
12 -- 指定索引來連接 table
13 print("連接后的字符串 ",table.concat(fruits, ", ", 2, 3))
14 
15 --執行結果
16 --[[
17 連接后的字符串     bananaorangeapple
18 連接后的字符串     banana, orange, apple
19 連接后的字符串     orange, apple
20 --]]

[2] 插入和移除

 1 --table.insert (table, [pos,] value):
 2 --在table的數組部分指定位置(pos)插入值為value的一個元素. pos參數可選, 默認為數組部分末尾.
 3 --table.remove (table [, pos])
 4 --返回table數組部分位於pos位置的元素. 其后的元素會被前移. pos參數可選, 默認為table長度, 即從最后一個元素刪起。
 5 
 6 
 7 fruits = {"banana", "orange", "apple"}
 8 
 9 -- 在末尾插入
10 table.insert(fruits, "mango")
11 print("索引為 4 的元素為 ", fruits[4])
12 
13 -- 在索引為 2 的鍵處插入
14 table.insert(fruits, 2, "grapes")
15 print("索引為 2 的元素為 ", fruits[2])
16 
17 print("最后一個元素為 ", fruits[5])
18 
19 table.remove(fruits)
20 print("移除后, 最后一個元素為 ", fruits[5])
21 
22 table.remove(fruits, 1)
23 print("移除后, 索引為 1 的元素為  ", fruits[1])
24 
25 --[[
26 索引為 4 的元素為     mango
27 索引為 2 的元素為     grapes
28 最后一個元素為     mango
29 移除后, 最后一個元素為     nil
30 移除后, 索引為 1 的元素為      grapes
31 --]]

[3] 排序

 1 -table.sort (table [, comp])
 2 --對給定的table進行升序排序。
 3 
 4 --3.1 默認排序示例
 5 fruits = {"banana", "orange", "apple", "grapes", "melon"}
 6 print("排序前")
 7 for k, v in ipairs(fruits) do
 8     print(k, v)
 9 end
10 --排序
11 table.sort(fruits)
12 print("排序后")
13 for k, v in ipairs(fruits) do
14     print(k, v)
15 end
16 
17 --執行結果
18 --[[
19 排序前
20 1    banana
21 2    orange
22 3    apple
23 4    grapes
24 5    melon
25 排序后
26 1    apple
27 2    banana
28 3    grapes
29 4    melon
30 5    orange
31 --]]
32 
33 --3.2 鍵值排序
34 local test1 = {a = 1, f = 9, d = 2, c = 8, b = 5}
35 local key_test = {}
36 for val in pairs(test1) do
37    table.insert(key_test, val)   --提取test1中的鍵值插入到key_test表中
38 end
39 
40 table.sort(key_test)
41 for i, v in pairs(key_test) do
42    print(v, test1[v])
43 end
44 
45 --執行結果
46 --[[
47 a    1
48 b    5
49 c    8
50 d    2
51 f    9
52 ]]
53 
54 --3.3 值排序之數組模式
55 local test0 = {1, 9, 2, 8, 3, 7, 4, 6}
56 table.sort(test0)  --從小到大排序,默認方式
57 for i, v in pairs(test0) do
58    io.write(v.." ")
59 end
60 
61 print("");
62 
63 table.sort(test0, function(a, b) return a > b end) --從大到小排序
64 for i, v in pairs(test0) do
65    io.write(v.." ")
66 end
67 print(" ")
68 
69 --[[
70 1 2 3 4 6 7 8 9
71 9 8 7 6 4 3 2 1
72 ]]
73 
74 --3.4 值排序之表單模式
75 local test2 =
76 {
77     {id = 1, name = "zhao"},
78     {id = 9, name = "liu"},
79     {id = 2, name = "wang"},
80     {id = 8, name = "xi"},
81     {id = 5, name = "qin"},
82 }
83 table.sort(test2, function(a,b) return a.id < b.id end)
84 for i in pairs(test2) do
85    print(test2[i].id, test2[i].name)
86 end
87 --[[
88 1    zhao
89 2    wang
90 5    qin
91 8    xi
92 9    liu
93 ]]

[4] 待續

9.7 計算表長度

 1 fruits = {"banana", "orange", "apple", "grapes", "melon", nil, "peach"}
 2 print(#fruits)             --> 7
 3 print(table.getn(fruits))  --> 7
 4 
 5 local myTable1 = {1, 2, 3}
 6 print("table1 length :: ", table.getn(myTable1))   --> 3
 7 
 8 local myTable2 = {1, a = 2, 3}
 9 print("table2 length :: ", table.getn(myTable2))   --> 2
10 print(myTable2.a)             --> 2
11 
12 
13 local myTable3 = {[1] = 2, [2] = 3, [3] = 10}
14 print("table3 length :: ", table.getn(myTable3))   --> 3
15 
16 local myTable4 = {[1] = 1, [2] = 2, [4] = 4}
17 print("table4 length :: ", table.getn(myTable4))   --> 4
18 
19 local myTable5 = {[1] = 1, [2] = 2, [5] = 5}
20 print("table5 length :: ", table.getn(myTable5))   --> 2
21 
22 local myTable6 = {1, [3] = 3, 4}
23 print("table6 length :: ", table.getn(myTable6))   --> 3
24 
25 local myTable7 = {1, nil}
26 print("table7 length :: ", table.getn(myTable7))   --> 1
27 
28 local myTable8 = {1, nil, 2}
29 print("table8 length :: ", table.getn(myTable8))   --> 3
30 
31 local myTable9 = {1, nil, 2, nil}
32 print("table9 length :: ", table.getn(myTable9))   --> 1
33 
34 local myTable10 = {1, nil, 2, nil, 3, nil}
35 print("table10 length :: ", table.getn(myTable10))   --> 3
36 
37 local myTable11 = {1, nil, 2, nil, 3, nil, 4, nil}
38 print("table11 length :: ", table.getn(myTable11))   --> 1

Lua里計算表長度可以使用“#”或者getn接口。示例如下:

你看懂了?你看不懂?難道真看不懂?難道我寫錯了?

唉~  看不懂就對了。。。。我也看不懂。。。待剖析源碼。

9.8 表其他待續

(10)總結

每種數據類型都各有特點,掌握得熟練還需多應用與摸索學習。

【3】總結

Lua是動態類型語言,變量不要類型定義,只需要為變量賦值。值可以存儲在變量中,作為參數傳遞或結果返回。

 

Good Good Study, Day Day Up.

順序 選擇 循環 總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM