声明:这是从网上看来的,方便学习,整理到简书上的,作者还是个权戏粉,233!
正文:
— 单行注释
–[[
[多行注释]
–]]
———-
– 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 = nil
aBoolValue = 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 ‘no’
karlSum = 0
for i = 1, 100 do — 像 Matlab 一样的递增语法,包括两端,如同数学中[1, 100]
karlSum = karlSum + i
end
— Step 为 2 递减的方式 ‘100, 1, -2’
for j = 100, 1, -2 then print(j) end
— 综上,范围可表示为 “begin, end [, step]”
— 另一个循环控制
num = 23
repeat
print(‘凡人必有一死’)
num = num – 1
until 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 end
end
a1 = adder(9)
a2 = adder(36)
print(a1(16)) –> 25
print(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, 42
end
x, y = bar(‘zaphod’) –> “zaphod nil nil”
— x = 4, y = 8, 其余值被忽略
— 函数与其他类型一样为一等公民
— 同样有 local/global 之分
— 像 Javascript 一样定义
function f(x) return x * x end
f = function (x) return x * x end
print ‘Hello World!’ — 只有一个`字符串`参数时可省略括号
———-
– 3. 表(Table)
———-
— 表是 Lua 中唯一的复合类型
— 像 PHP 中的数组或 Javascript 中的 Object 一样
— 可用作 list/dict/map
— 默认以字符串作为 key
t = {key1 = ‘value1’, key2 = false}
— 像 Javascript 一样以 . 取值
print(t.key1) –> “value1”
t.key3 = {} — 加入新的键值对
t.key2 = nil — 销毁一组键值对
— 理论上任何非 nil 的变量都可以作为 key
u = {[‘@!#’] = ‘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) end
h{key1 = ‘Sonmi~451’} –> “Sonmi~451”
for key, val in pairs(u) do — 像 Python 一样的键值迭代
print(key, val)
end
— 像 Javascript 一样的全局作用域 _G
print(_G[‘_G’] == _G) –> true
— 省略 key 之后即可变身为 list
— 实际上是以递增自然数为 key
v = {‘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 sum
end
setmetatable(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) 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.
end
function Dog:makeSound() — 6.
print(‘I say ‘ .. self.sound)
end
mrDog = 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)
end
seymour = LoudDog:new()
seymour:makeSound() –> “woof woof woof”
———-
– 4. 模块
———-
— 以下来自文件 mod.lua
local M = {}
local function sayMyName()
print(‘Hrunkner’)
end
function M.sayHello()
print(‘Why hello there’)
sayMyName()
end
return 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 是不缓存的版本的 require
dofile(“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!”