lua算術運算和關係運算metamethods

2021-09-25 09:58:18 字數 2978 閱讀 8389

--[[

說明1.以下使用的metamethod都是lua核心metamethod,使用的時候可以採用相應的操作符,如:__add可以解釋成+。

2.metamethod需要放在metatable中使用

算術運算子對應的域:

__add(+), __sub(-), __mul(*), __div(/), __unm(-負), __pow(^冪)

關係運算子對應的域:

__eq(==), __lt(<), __le(<=)

無~=, >, >=, 可以通過上述關係運算子not操作來實現

其他:字串連線操作: __concat(..)

轉化為字串操作:__tostring,當使用函式print列印該變數時,首先利用該變數的__tostring函式進行字串的轉化

保護元表資訊:__metatable

]]set = {}

set.mt = {}

--[[

算術運算

]]function set.new(t)

local s = {}

setmetatable(s, set.mt)

for _, item in ipairs(t) do

s[item] = true

endreturn s

end-- 求集合並集

function set.union(s1, s2)

-- 兩個集合的metatable必須相等,才能執行並集操作

if getmetatable(s1) ~= set.mt or

getmetatable(s2) ~= set.mt then

error("attempt to add a set with a non-set value", 2)

endlocal res = set.new({})

for item in pairs(s1) do

res[item] = true

endfor item in pairs(s2) do

res[item] = true

endreturn res

end-- 求集合交集

function set.intersection(s1, s2)

if getmetatable(s1) ~= set.mt or

getmetatable(s2) ~= set.mt then

error("attempt to multify a set with a non-set value", 2)

endlocal res = set.new({})

for item in pairs(s1) do

res[item] = s2[item]

endreturn res

end-- 將集合轉化為字串

function set.tostring(s)

local res = ""

end-- 列印集合

function set.print(s)

print(set.tostring(s))

endset.mt.__add = set.union -- 設定+運算實現函式,集合並集

set.mt.__mul = set.intersection -- 設定*運算實現函式,集合交集

set.mt.__tostring = set.tostring

s1 = set.new()

s2 = set.new()

print(s1)

print(s2)

print(s1 + s2)

print(s1 * s2)

--[[

關係運算

]]-- 小於等於

set.mt.__le = function(s1, s2)

for item in pairs(s1) do

-- s1有的,s2中沒有,則s2不包含s1

if not s2[item] then

return false

endend

return true

end-- 小於

set.mt.__lt = function(s1, s2)

--[[

s1 <= s2,而且s1 ~= s2,

當s1 <= s2且s2 <= s1時,表示s1 == s2,所以這裡增加乙個判斷條件是not(s2 <= s1) ]]

return s1 <= s2 and not(s2 <= s1)

end-- 等於

set.mt.__eq = function(s1, s2)

return s1 <= s2 and s2 <= s1

ends3 = set.new()

s4 = set.new()

print(s3 < s4)

print(s3 == s4)

print(s3 <= s4)

print(s3 == (s3 * s4))

s5 =

print(3 == "a")

print(3 == s3) -- 相等比較,混合型別,則返回false,不會丟擲異常

print(s5 == s3) -- 相等比較,相同型別,metadata不同,則返回false,不會丟擲異常

--print(3 > s3) -- 非相等比較,混合型別,則直接丟擲異常

--print(s5 > s3) -- 非相等比較,相同型別,metadata不同,則直接丟擲異常

--[[

為元表設定屬性__metatable,保護元表不會被讀取,不會被修改

]]set.mt.__metatable = "none of your bussiness"

s6 = set.new({})

print(getmetatable(s)) -- 獲得元表,會直接返回上面設定的__metatable屬性的值

setmetatable(s6, {}) -- 修改s6的元表,將會丟擲異常

指標運算 算術運算 關係運算

是不是對指標的任何運算都是合法的呢?答案是它可以執行某些運算,但並非所有的運算都合法。除了加法運算之外,你還可以對指標執行一些其他運算,但並不是很多。指標加上乙個整數的結果是另乙個指標。問題是,它指向 如果你將乙個字元指標加1,運算結果產生的指標指向記憶體中的下乙個字元。float佔據的記憶體空間不...

指標運算 算術運算 關係運算

是不是對指標的任何運算都是合法的呢?答案是它可以執行某些運算,但並非所有的運算都合法。除了加法運算之外,你還可以對指標執行一些其他運算,但並不是很多。指標加上乙個整數的結果是另乙個指標。問題是,它指向 如果你將乙個字元指標加1,運算結果產生的指標指向記憶體中的下乙個字元。float佔據的記憶體空間不...

指標運算 算術運算 關係運算

c c 允許將指標和整數進行相加操作,加1的結果就是等於原來的位址值加上指向物件占用的位元組數 如 int p int malloc sizeof int 5 p 1 表示p指向記憶體位址加4個位元組 兩個指標如果指向同乙個陣列,則兩個指標進行算術運算才有意義,即 int p int malloc ...