Lua 学习心得

November 06, 2016 12:41


table 数据结构

数组

list = {'a', 'b', 'c'}
print(list[1]) -- 'a' 好吧,他的索引是从 1 开始的
print(#list) -- 3, 数组长度

list[4] = 'd'
print(#list) -- 4,

list['a'] = 'hello'
print(#list) -- 4, 非数字索引会直接忽略

list[7] = 1
print(#list) -- 4, 中间断了,只计算了连续长度

list2 = {1, 3, nil, 30}
print(#list) -- 4, 直接定义的,长度还是 4

结果就是直接使用 #list 取长度会有各种坑,直接 for i in pairs(list) 遍历所有元素最靠谱了

table = {a = 1, b = 2, name = 'Jon'}
print(table['a']) -- 1
print(table.name) -- Jon

看到这里应该已经知道了,其实数组和表都是一个东西,下面的定义是相等的

{'a', 'b', 'c'}
{[1] = 'a', [2] = 'b', [3] = 'c'} -- 上面也就是简化后的定义了

For 循环

For step

for i = 0, 10, 3 do
  print(i)
end
-- print 0 3 6 9

For table

list = {a = 1, b = 2, c = 3}

-- pairs 应该是为 list 生成了一个迭代函数,用来遍历所有 key val
for key, val in pairs(list) do
  print(key .. ': ' .. val) -- 字符串拼接都是使用 .. 两个点
end

函数

定义

function hello()
  print("Hello World")
end

hello()

匿名定义

what = function ()
  print("What's your name?")
end

what()

定义冒号函数(语法糖)

point = {x = 10, y = 20}

function point:print()
  print(self.x, self.y)
end

point:print() -- 相当于调用时将 print 函数的 self 设置为自身
point.print(point) -- 和上面的等效,调用 print 显示的传入 self (也就是 point)

其实定义 point:printpoint.print(self) 是等效的

a = {val = 'hello'}

function a.show(self)
  print(self.val)
end

a.show(a) --> hello
a:show() --> hello

这个语法糖后面会有相关的应用

Metatable

重定义元操作

mt = {}
-- `+` 操作在 metatable 对应的方法是 `__add`,
function mt.__add(t1, t2)
  return {price = t1.price + t2.price}
end

item1 = setmetatable({price = 10}, mt) -- 设置 table 的 metatable 为 mt,并返回 table
item2 = setmetatable({price = 20}, mt)

print((item1 + item2).price) -- 已经可以操作 item1 + item2 了

metatable 中有非常多的元方法可以去(重)定义,下面一个例子定义 __index 元方法

mt = {type = "human"}
-- 当找不到某个方法或属性的定义时,从 __index 中继续查询
-- __index 对应的值可以是一个 table, 也可以是一个 function 
mt.__index = mt
jon = setmetatable({weight = 60}, mt)
print(jon.type) -- human
print(jon.weight) -- 60

使用 metatable 模拟 class

A = {}
A.__index = A -- 用于实例找不到的方法再查询类 A 的方法

function A.new(name, val)
  local obj = setmetatable({}, A) -- 新的实例 obj

  obj.name = name
  obj.val = val

  print(obj.name .. ': ' .. obj.val)

  return obj
end

function A:show()
  print(self.name .. ': ' .. self.val)
end

function A:plus(val)
  self.val = self.val + val
  print(self.name .. ': + ' .. val .. ' => ' .. self.val)
end


B = {}
setmetatable(B, A) -- 元表为 A,继承 A 的所有 function
B.__index = B

function B.new(name, val, n)
  local obj = setmetatable(A.new(name, val), B)

  obj.n = n

  return obj
end

function B:plus(val)
  self.val = self.val + val * self.n
  print(self.name .. ': + ' .. self.n .. ' * ' .. val .. ' => ' .. self.val)
end

a1 = A.new('a1', 1)
a2 = A.new('a2', 2)
b1 = B.new('b1', 1, 2)
b2 = B.new('b2', 2, 4)

a1:plus(1)
a1:plus(2)
a2:plus(3)
a1:show()
b1:plus(1)
b1:plus(2)
b2:plus(3)
b1:show()

Comments: