轉載自: https://blog.csdn.net/qq_15437667/article/details/75042526
1 -- 單行注釋 2 --[[ 3 [多行注釋] 4 --]] 5 6 ---------- 7 - 1. 變量 & 控制流 8 ---------- 9 num = 23 -- 數字都是雙精度 10 str = 'aspythonstring' -- 像 Python 一樣不可變 11 str = "aspythonuse" -- 可以雙引號 12 str = [[ 13 像 Python 的多行注釋可用於 14 表示多行字符串一樣 15 方便 16 ]] 17 18 bol = nil -- 未定義;支持垃圾回收 19 20 -- 縮進只為易讀性,像 Matlab 一樣以 end 結尾 21 while num < 50 do 22 num = num + 1 -- 沒有 ++ 或 += 自增操作符號 23 end 24 25 -- IF 條件開關 26 if num > 40 then 27 print('> 40') 28 elseif s ~= 'aspython' then -- ~= 表示 != 29 io.write('s is not aspython') -- 風騷的標准輸出 30 else 31 thisIsGlobal = 5 -- 駝峰式命名 32 -- 顯示聲明局部變量(像 Javascript 一樣) 33 local line = io.read() 34 35 -- .. 作為字符串連接符 36 print('凜冬將至' .. line) 37 end 38 39 -- 引用未定義變量將返回 nil ,這不是錯誤 40 foo = anUnknownVariable -- 等價於 foo = nil 41 42 aBoolValue = false 43 -- 只有 nil 與 false 為邏輯假; 數字 0 與空字串 '' 為真! 44 if not aBoolValue then print('false') end 45 46 -- 像 Python 一樣運用 'or' 和 'and' 47 -- 得到 C 語言中 a ? b : c 的效果;需注意 b = false 或 nil 的情況 48 ans = aBoolValue and 'yes' or 'no' 49 50 karlSum = 0 51 for i = 1, 100 do -- 像 Matlab 一樣的遞增語法,包括兩端,如同數學中[1, 100] 52 karlSum = karlSum + i 53 end 54 55 -- Step 為 2 遞減的方式 '100, 1, -2' 56 for j = 100, 1, -2 then print(j) end 57 58 -- 綜上,范圍可表示為 "begin, end [, step]" 59 60 -- 另一個循環控制 61 num = 23 62 repeat 63 print('凡人必有一死') 64 num = num - 1 65 until num == 0 66 67 68 ---------- 69 - 2. 函數 70 ---------- 71 function fib(n) 72 if n < 2 then return 1 end 73 return fib(n - 2) + fib(n - 1) 74 end 75 76 -- Javascript 一樣的匿名函數與閉包 77 function adder(x) 78 -- 返回一個函數 79 -- 閉包內封存 x 值 80 return function (y) return x + y end 81 end 82 a1 = adder(9) 83 a2 = adder(36) 84 print(a1(16)) --> 25 85 print(a2(64)) --> 100 86 87 -- 遇到不匹配的列表長度時 88 -- 過長的變量將被賦予 nil 89 -- 過長的值將被忽略 90 91 x, y, z = 1, 2, 3, 4 -- 4 將被忽略 92 function bar(a, b, c) 93 print(a, b, c) 94 return 4, 8, 15, 16, 23, 42 95 end 96 x, y = bar('zaphod') --> "zaphod nil nil" 97 -- x = 4, y = 8, 其余值被忽略 98 99 -- 函數與其他類型一樣為一等公民 100 -- 同樣有 local/global 之分 101 -- 像 Javascript 一樣定義 102 function f(x) return x * x end 103 f = function (x) return x * x end 104 105 print 'Hello World!' -- 只有一個`字符串`參數時可省略括號 106 107 ---------- 108 - 3. 表(Table) 109 ---------- 110 -- 表是 Lua 中唯一的復合類型 111 -- 像 PHP 中的數組或 Javascript 中的 Object 一樣 112 -- 可用作 list/dict/map 113 114 -- 默認以字符串作為 key 115 t = {key1 = 'value1', key2 = false} 116 -- 像 Javascript 一樣以 . 取值 117 print(t.key1) --> "value1" 118 t.key3 = {} -- 加入新的鍵值對 119 t.key2 = nil -- 銷毀一組鍵值對 120 121 -- 理論上任何非 nil 的變量都可以作為 key 122 u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'} 123 print(u[6.28]) --> "tau" 124 a = u['@!#'] -- a = 'qbert' 125 b = u[{}] -- b = nil;像 Javascript 一樣 {} 會創建新的對象 126 -- 因此不要用蛋疼的 key 值,老老實實用字串或數字 127 128 -- 同字符串一樣,只有一個表作為函數的參數時可以省略括號 129 -- 為了一個括號增加閱讀難度,得不償失 130 function h(x) print(x.key1) end 131 h{key1 = 'Sonmi~451'} --> "Sonmi~451" 132 133 for key, val in pairs(u) do -- 像 Python 一樣的鍵值迭代 134 print(key, val) 135 end 136 137 -- 像 Javascript 一樣的全局作用域 _G 138 print(_G['_G'] == _G) --> true 139 140 -- 省略 key 之后即可變身為 list 141 -- 實際上是以遞增自然數為 key 142 v = {'value1', 'value2', 1.21, 'gigawatts'} 143 for i = 1, #v do -- 像 Bash 一樣,#v 表示列表長度 144 print(v[i]) -- 像 Matlab 一樣,列表索引從 1 開始 145 end 146 147 ---------- 148 - 3.1 Metatables & metamethods 149 ---------- 150 -- 元表(metatable)就是表的表,像 Javascript 的原型(prototype)一樣 151 -- 為表重載一些元方法(metamethods) 152 153 f1 = {a = 1, b = 2} 154 f2 = {a = 2, b = 3} 155 -- s = f1 + f2 為錯 156 157 mm = {} 158 function mm.__add(x, y) 159 sum = {} 160 sum.a = x.a + y.a 161 sum.b = x.b + y.b 162 return sum 163 end 164 165 setmetatable(f1, mm) 166 setmetatable(f2, mm) 167 168 -- 實際調用 f1 的 metatable 中的 __add(f1, f2) 169 -- 只為 f1 設置元表也可以 170 s = f1 + f2 -- s = {a = 3, b = 5} 171 172 -- s2 = s + s 為錯,s 未定義元表 173 174 -- __index 元方法重載表中 key 的提取符號 `.` 175 defaultFavs = {animal = 'gru', food = 'donuts'} 176 myFavs = {food = 'pizza'} 177 setmetatable(myFavs, {__index = defaultFavs}) 178 food = myFavs.food 179 180 -- Lua 中的值都具有元方法,只有 Table 可以重載 181 -- 所有元方法如下 182 183 -- __add(a, b) for a + b 184 -- __sub(a, b) for a - b 185 -- __mul(a, b) for a * b 186 -- __div(a, b) for a / b 187 -- __mod(a, b) for a % b 188 -- __pow(a, b) for a ^ b 189 -- __unm(a) for -a 190 -- __concat(a, b) for a .. b 191 -- __len(a) for #a 192 -- __eq(a, b) for a == b 193 -- __lt(a, b) for a < b 194 -- __le(a, b) for a <= b 195 -- __index(a, b) <fn or a table> for a.b 196 -- __newindex(a, b, c) for a.b = c 197 -- __call(a, ...) for a(...) 198 199 ---------- 200 - 3.2 類風格的 Table 與繼承 201 ---------- 202 203 -- 像 Javascript 一樣並沒有內置 Class 204 -- 但可以通過 Table `{}` 實現 205 206 Dog = {} -- 1. 207 function Dog:new() -- 2. 208 newObj = {sound = 'woof'} -- 3. 209 self.__index = self -- 4. 210 return setmetatable(newObj, self) -- 5. 211 end 212 function Dog:makeSound() -- 6. 213 print('I say ' .. self.sound) 214 end 215 216 mrDog = Dog:new() -- 7. 217 mrDog:makeSound() --> "I say woof" 218 219 -- 1. Dog 像類但實際是 Table 220 -- 2. Dog:new(...) := Dog.new(self, ...) 221 -- 3. newObj 作 Dog 的實例 222 -- 4. self 是 Lua 中默認的參數,在這里 self = Dog 223 -- 繼承的時候可以改變 224 -- self.__index 與 self 的元方法 __index 不是一回事 225 -- self = {__index = self, metatable = {__index = ...}} 226 -- 5. setmetatable(newObj, self) 相當於 setmetatable(newObj, {__index = self}) 227 -- 賦予實例所有類方法 228 -- 6. 同 2. 229 -- 7. mrDog = Dog.new(Dog) 230 231 -- 繼承 232 LoudDog = Dog:new() 233 function LoudDog:makeSound() 234 s = self.sound .. ' ' 235 print(s .. s .. s) 236 end 237 seymour = LoudDog:new() 238 seymour:makeSound() --> "woof woof woof" 239 240 ---------- 241 - 4. 模塊 242 ---------- 243 244 -- 以下來自文件 mod.lua 245 local M = {} 246 247 local function sayMyName() 248 print('Hrunkner') 249 end 250 251 function M.sayHello() 252 print('Why hello there') 253 sayMyName() 254 end 255 return M 256 -- 以上 257 -- 回到主文件 258 local mod = require('mod') -- 運行 mod.lua 中的代碼 259 -- 操作同下 260 local mod = (function() 261 -- 像 Javascript 一樣 262 --[[ 263 mod.lua 中的代碼 264 ]]-- 265 end)() 266 267 mod.sayHello() --> "Why hello there" 268 mod.sayMyName() --> 錯!sayMyName() 是 mod.lua 中的局部變量 269 270 -- require 返回的值將被緩存 271 -- 即使多次調用 require 被調用文件也只運行一次 272 273 -- mod2.lua 包含 print("mod2") 274 local a = require("mod2") --> "mod2" 275 local b = require("mod2") -- 不輸出, 實際為 b = a 276 277 -- dofile 是不緩存的版本的 require 278 dofile("mod2") --> "mod2" 279 dofile("mod2") --> "mod2" 280 281 -- loadfile 讀取文件但不執行 282 -- 勘誤:f = loadfile('mod2'),需加后綴名,否則找不到文件 283 f = loadfile('mod2.lua') 284 f() --> "mod2" 285 286 -- loadstring 讀取代碼字符串 287 f = loadstring("print('Lua is cool!')") 288 f() --> "Lua is cool!" 289 290 ---------- 291 - 5. 參考,略 292 ----------