大粨兔奶糖

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

lua metatable (元表)

概述

普通 table 类型的表仅能够做一些单表操作, 无法进行一些特殊的以及两个表的操作, 比如 table1 + table2, print(table3)

lua 的元表可以理解为一个存储操作方法的 table, 将表指定某个元表, 其实就是将一些操作绑定到了原表上

语法定义

setmetatable(table, metatable)

getmetatable(table)

示例程序

mytable1 = {name = "liao", age = 18}
mymetatable1 = {sex = "male"}
setmetatable(mytable1, mymetatable1)

mytable2 = setmetatable({}, {})

metat = getmetatable(mytable1)

for k, v in pairs(mytable1) do
	print(k, v)
end

常用元方法

元方法有点类似于 php 的魔术方法的意思

__index

示例程序

mytable = setmetatable({k1 = "v1"}, {
	__index = function(mytable, k)
		if k == "k2" then
			return "v2"
		else
			return nil
		end
	end
})

print(mytable.k1, mytable.k2, mytable.k3)

__newindex

示例程序

mymetatable = {}
mytable = setmetatable({k1 = "v1"}, {
	__newindex = mymetatable
})

mytable.k1 = "hello"
mytable.k2 = "world"

print(mytable.k1, mytable.k2, mymetatable.k1, mymetatable.k2)

// 若要将赋值赋给原表, 需要使用 rawset 函数
mymetatable2 = {}
mytable2 = {k1 = "v1"}

mymetatable2.__newindex = function(mytable2, k, v)
	rawset(mytable2, k, v)
end

__add

示例程序

local mytable1 = {1, 2, 3}
local mytable2 = {4, 5, 6}
local mymetatable = {}

// 将 t2 的数据加入 t1
mymetatable._add = function(t1, t2)
	for i = 1, #t2 do
		table.insert(t1, #t1 + 1, t2[i])
	end
	
	return t1
end

setmetatable(mytable1, mymetatable)

local mytable3 = mytable1 + mytable2

for k, v in pairs(mytable3) do
	print(k, v)
end

__sub

示例程序

local mytable1 = {1, 2, 3, 4, 5, 6}
local mytable2 = {2, 3}
local mymetatable = {}

function removeFromTable(t, val)
	for k, v in pairs(t) do
		if v == val then
			table.remove(t, k)
		end
	end
	
	return t
end

mymetatable.__sub = function(t1, t2)
	for i = 1, #t2 do
		t1 = removeFromTable(t1, t2[i])
	end
	
	return t1
end

setmetatable(mytable1, mymetatable)

local mytable3 = mytable1 - mytable2

for k, v in pairs(mytable3) do
	print(k, v)
end

__mul

示例程序

local mytable1, mytable2, mymetatable = {1, 2, 3}, {4, 5}, {}

mymetatable.__mul = function(t1, t2)
	for i = 1, #t1 do
		local m1, m2 = t1[i], t2[i]
		if not m2 then
			m2 = 1
		end
		
		t1[i] = m1 * m2
	end
	
	return t1
end

setmetatable(mytable1, mymetatable)

local mytable3 = mytable1 * mytable2

for k, v in pairs(mytable3) do
	print(k, v)
end

__div

示例程序

local t1, t2, meta = {10, 9, 8}, {5, 4}, {}

meta.__div = function(t1, t2)
	for i = 1, #t1 do
		local d1, d2 = t1[i], t2[i]
		if not d2 then
			d2 = 1
		end
		t1[i] = d1 / d2
	end
	
	return t1
end

setmetatable(t1, meta)

local t3 = t1 / t2

for k, v in pairs(t3) do
	print(k, v)
end

__mod

示例程序

local t1, t2, meta = {10, 9, 8}, {5, 4}, {}

meta.__mod = function(t1, t2)
	for i = 1, #t1 do
		if not t2[i] or t2[i] == 0 then
			break
		end
		t1[i] = t1[i] % t2[i]
	end
	
	return t1
end

setmetatable(t1, meta)

local t3 = t1 % t2

for k, v in pairs(t3) do
	print(k, v)
end

__unm

示例程序

local t1, meta = {1, 2, 3}, {}

meta.__unm = function(t1)
	for i = 1, #t1 do
		t1[i] = -t1[i]
	end
	
	return t1
end

setmetatable(t1, meta)

local t3 = -t1

for k, v in pairs(t3) do
	print(k, v)
end

__concat

示例程序

local t1, t2, meta = {1, 2, 3}, {4, 5, 6}, {}

meta.__concat = function(t1, t2)
	for i = 1, #t1 do
		t1[i] = t1[i] .. t2[i]
	end
	
	return t1
end

setmetatable(t1, meta)

local t3 = t1 .. t2

for k, v in pairs(t3) do
	print(k, v)
end

__eq

示例程序

local t1, t2, meta = {1, 2, 3}, {1, 2, 3}, {}

meta.__eq = function(t1, t2)
	for i = 1, #t1 do
		if t1[i] ~= t2[i] then
			return false
		end
	end
	
	return true
end

setmetatable(t1, meta)

local compare = t1 == t2

print(compare)

__lt

示例程序

local t1, t2, meta = {1, 2, 3}, {4}, {}

meta.__lt = function(t1, t2)
	local sum1, sum2 = 0, 0
	for i = 1, #t1 do
		sum1 = sum1 + t1[i]
	end
	
	for i = 1, #t2 do
		sum2 = sum2 + t2[i]
	end
	
	if sum1 < sum2 then
		return true
	else
		return false
	end
end

setmetatable(t1, meta)

local compare = t1 < t2

print(compare)

__le

示例程序

local t1, t2, meta = {1, 2, 3}, {1, 2, 3}, {}

meta.__le = function(t1, t2)
	local sum1, sum2 = 0, 0
	for i = 1, #t1 do
		sum1 = sum1 + t1[i]
	end
	
	for i = 1, #t2 do
		sum2 = sum2 + t2[i]
	end
	
	if sum1 <= sum2 then
		return true
	else
		return false
	end
end

setmetatable(t1, meta)

local compare = t1 <= t2

print(compare)

__call

示例程序

local t1, t2, meta = {1}, {2, 3}, {}

meta.__call = function(t1, t2)
	local sum = 0
	for i = 1, #t1 do
		sum = sum + t1[i]
	end
	
	for i = 1, #t2 do
		sum = sum + t2[i]
	end
	
	return sum
end

setmetatable(t1, meta)

local sum = t1(t2)

print(sum)

__tostring

示例程序

local t1, meta = {1, 2, 3}, {}

meta.__tostring = function(t)
	local str = ''
	for i = 1, #t do
		str = str .. t[i] .. "###"
	end
	
	return str
end

setmetatable(t1, meta)

print(t1)
posted on 2017-04-20 17:05  大粨兔奶糖  阅读(172)  评论(0编辑  收藏  举报