首页 > 代码库 > Lua 语言 15 分钟快速入门【译】

Lua 语言 15 分钟快速入门【译】

 

 

  • 原文网址:http://defsniky.com/posts/2014-06-05-learn-lua-in-15-minutes.html
  • 英文网址:http://tylerneylon.com/a/learn-lua/
-- 单行注释--[[    [多行注释]--]]----------- 1. 变量 & 控制流----------num = 23 -- 数字都是双精度str = aspythonstring -- 像 Python 一样不可变str = "aspythonuse" -- 可以双引号str = [[        像 Python 的多行注释可用于        表示多行字符串一样        方便    ]]bol = nil -- 未定义;支持垃圾回收-- 缩进只为易读性,像 Matlab 一样以 end 结尾while num < 50 do    num = num + 1 -- 没有 ++ 或 += 自增操作符号end-- IF 条件开关if num > 40 then    print(> 40)elseif s ~= aspython then -- ~= 表示 !=    io.write(s is not aspython) -- 风骚的标准输出else    thisIsGlobal = 5 -- 驼峰式命名    -- 显示声明局部变量(像 Javascript 一样)    local line = io.read()    -- .. 作为字符串连接符    print(凛冬将至 .. line)end-- 引用未定义变量将返回 nil ,这不是错误foo = anUnknownVariable  -- 等价于 foo = nilaBoolValue = false-- 只有 nil 与 false 为逻辑假; 数字 0 与空字串 ‘‘ 为真!if not aBoolValue then print(false) end-- 像 Python 一样运用 ‘or‘ 和 ‘and‘-- 得到 C 语言中 a ? b : c 的效果;需注意 b = false 或 nil 的情况ans = aBoolValue and yes or nokarlSum = 0for i = 1, 100 do -- 像 Matlab 一样的递增语法,包括两端,如同数学中[1, 100]    karlSum = karlSum + iend-- Step 为 2 递减的方式 ‘100, 1, -2‘for j = 100, 1, -2 then print(j) end-- 综上,范围可表示为 "begin, end [, step]"-- 另一个循环控制num = 23repeat    print(凡人必有一死)    num = num - 1until num == 0----------- 2. 函数----------function fib(n)    if n < 2 then return 1 end    return fib(n - 2) + fib(n - 1)end-- Javascript 一样的匿名函数与闭包function adder(x)    -- 返回一个函数    -- 闭包内封存 x 值    return function (y) return x + y endenda1 = adder(9)a2 = adder(36)print(a1(16))  --> 25print(a2(64))  --> 100-- 遇到不匹配的列表长度时-- 过长的变量将被赋予 nil-- 过长的值将被忽略x, y, z = 1, 2, 3, 4 -- 4 将被忽略function bar(a, b, c)    print(a, b, c)    return 4, 8, 15, 16, 23, 42endx, y = bar(zaphod)  --> "zaphod  nil nil"-- x = 4, y = 8, 其余值被忽略-- 函数与其他类型一样为一等公民-- 同样有 local/global 之分-- 像 Javascript 一样定义function f(x) return x * x endf = function (x) return x * x endprint Hello World! -- 只有一个`字符串`参数时可省略括号----------- 3. 表(Table) ------------ 表是 Lua 中唯一的复合类型-- 像 PHP 中的数组或 Javascript 中的 Object 一样-- 可用作 list/dict/map-- 默认以字符串作为 keyt = {key1 = value1, key2 = false}-- 像 Javascript 一样以 . 取值print(t.key1) --> "value1"t.key3 = {} -- 加入新的键值对t.key2 = nil -- 销毁一组键值对-- 理论上任何非 nil 的变量都可以作为 keyu = {[@!#] = qbert, [{}] = 1729, [6.28] = tau}print(u[6.28])  --> "tau"a = u[@!#] -- a = ‘qbert‘b = u[{}] -- b = nil;像 Javascript 一样 {} 会创建新的对象          -- 因此不要用蛋疼的 key 值,老老实实用字串或数字-- 同字符串一样,只有一个表作为函数的参数时可以省略括号-- 为了一个括号增加阅读难度,得不偿失function h(x) print(x.key1) endh{key1 = Sonmi~451}  --> "Sonmi~451"for key, val in pairs(u) do  -- 像 Python  一样的键值迭代    print(key, val)end-- 像 Javascript 一样的全局作用域 _Gprint(_G[_G] == _G) --> true-- 省略 key 之后即可变身为 list-- 实际上是以递增自然数为 keyv = {value1, value2, 1.21, gigawatts}for i = 1, #v do  -- 像 Bash 一样,#v 表示列表长度    print(v[i])  -- 像 Matlab 一样,列表索引从 1 开始end----------- 3.1 Metatables & metamethods------------ 元表(metatable)就是表的表,像 Javascript 的原型(prototype)一样-- 为表重载一些元方法(metamethods)f1 = {a = 1, b = 2}f2 = {a = 2, b = 3}-- s = f1 + f2 为错mm = {}function mm.__add(x, y)  sum = {}  sum.a = x.a + y.a  sum.b = x.b + y.b  return sumendsetmetatable(f1, mm)setmetatable(f2, mm)-- 实际调用 f1 的 metatable 中的 __add(f1, f2)-- 只为 f1 设置元表也可以s = f1 + f2 -- s = {a = 3, b = 5}-- s2 = s + s 为错,s 未定义元表-- __index 元方法重载表中 key 的提取符号 `.`defaultFavs = {animal = gru, food = donuts}myFavs = {food = pizza}setmetatable(myFavs, {__index = defaultFavs})food = myFavs.food-- Lua 中的值都具有元方法,只有 Table 可以重载-- 所有元方法如下-- __add(a, b)                     for a + b-- __sub(a, b)                     for a - b-- __mul(a, b)                     for a * b-- __div(a, b)                     for a / b-- __mod(a, b)                     for a % b-- __pow(a, b)                     for a ^ b-- __unm(a)                        for -a-- __concat(a, b)                  for a .. b-- __len(a)                        for #a-- __eq(a, b)                      for a == b-- __lt(a, b)                      for a < b-- __le(a, b)                      for a <= b-- __index(a, b)  <fn or a table>  for a.b-- __newindex(a, b, c)             for a.b = c-- __call(a, ...)                  for a(...)----------- 3.2 类风格的 Table 与继承------------ 像 Javascript 一样并没有内置 Class-- 但可以通过 Table `{}` 实现Dog = {}                                -- 1.function Dog:new()                      -- 2.    newObj = {sound = woof}           -- 3.    self.__index = self                 -- 4.    return setmetatable(newObj, self)   -- 5.endfunction Dog:makeSound()                -- 6.    print(I say  .. self.sound)endmrDog = Dog:new()                       -- 7.mrDog:makeSound() --> "I say woof"-- 1. Dog 像类但实际是 Table-- 2. Dog:new(...) := Dog.new(self, ...)-- 3. newObj 作 Dog 的实例-- 4. self 是 Lua 中默认的参数,在这里 self = Dog--    继承的时候可以改变--    self.__index 与 self 的元方法 __index 不是一回事--    self = {__index = self, metatable = {__index = ...}}-- 5. setmetatable(newObj, self) 相当于 setmetatable(newObj, {__index = self})--    赋予实例所有类方法-- 6. 同 2.-- 7. mrDog = Dog.new(Dog)-- 继承LoudDog = Dog:new()function LoudDog:makeSound()    s = self.sound ..      print(s .. s .. s)endseymour = LoudDog:new()seymour:makeSound() --> "woof woof woof"----------- 4. 模块------------ 以下来自文件 mod.lualocal M = {}local function sayMyName()    print(Hrunkner)endfunction M.sayHello()    print(Why hello there)    sayMyName()endreturn M-- 以上-- 回到主文件local mod = require(mod) -- 运行 mod.lua 中的代码-- 操作同下local mod = (function()    -- 像 Javascript 一样    --[[        mod.lua 中的代码    ]]--end)()mod.sayHello() --> "Why hello there"mod.sayMyName() --> 错!sayMyName() 是 mod.lua 中的局部变量-- require 返回的值将被缓存-- 即使多次调用 require 被调用文件也只运行一次-- mod2.lua 包含 print("mod2")local a = require("mod2") --> "mod2"local b = require("mod2") -- 不输出, 实际为 b = a-- dofile 是不缓存的版本的 requiredofile("mod2") --> "mod2"dofile("mod2") --> "mod2"-- loadfile 读取文件但不执行-- 勘误:f = loadfile(‘mod2‘),需加后缀名,否则找不到文件f = loadfile(mod2.lua)f() --> "mod2"-- loadstring 读取代码字符串f = loadstring("print(‘Lua is cool!‘)")f() --> "Lua is cool!"----------- 5. 参考,略----------

 

Lua 语言 15 分钟快速入门【译】