此第一版是為 Lua 5.0 編寫的。儘管在很大程度上仍然適用於後續版本,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您還可以幫助 支援 Lua 專案。
![]() |
以 Lua 編程 | ![]() |
第二部分。表格和物件 第 13 章。元表和元方法 |
元表還允許我們通過元方法 __eq
(相等性)、__lt
(小於)和 __le
(小於或等於)賦予關聯運算子意義。其他三個關聯運算子沒有單獨的元方法,因為 Lua 將 a ~= b
轉換為 not (a == b)
,將 a > b
轉換為 b < a
,將 a >= b
轉換為 b <= a
。
(大括號:在 Lua 4.0 之前,所有順序運算子都轉換為一個運算子,方法是將 a <= b
轉換為 not (b < a)
。但是,當我們有偏序時(即,當我們類型中的所有元素沒有適當地排序時),這種轉換是不正確的。例如,由於非數字(NaN)的值,浮點數在大多數機器中沒有完全排序。根據目前幾乎所有硬體都採用的 IEEE 754 標準,NaN 表示未定義的值,例如 0/0
的結果。該標準規定,涉及 NaN 的任何比較都應導致 false。這意味著 NaN <= x
永遠為 false,但 x < NaN
也為 false。這意味著從 a <= b
到 not (b < a)
的轉換在這種情況下無效。)
在我們集合的範例中,我們遇到了類似的問題。集合中 <=
的一個顯而易見(且有用的)含義是集合包含:a <= b
表示 a
是 b
的子集。有了這個含義,a <= b
和 b < a
都可能是 false;因此,我們需要為 __le
(小於或等於)和 __lt
(小於)定義單獨的實作
Set.mt.__le = function (a,b) -- set containment for k in pairs(a) do if not b[k] then return false end end return true end Set.mt.__lt = function (a,b) return a <= b and not (b <= a) end最後,我們可以通過集合包含來定義集合相等性
Set.mt.__eq = function (a,b) return a <= b and b <= a end在這些定義之後,我們現在準備好比較集合
s1 = Set.new{2, 4} s2 = Set.new{4, 10, 2} print(s1 <= s2) --> true print(s1 < s2) --> true print(s1 >= s1) --> true print(s1 > s1) --> false print(s1 == s2 * s1) --> true
與算術元方法不同,關係元方法不支援混合類型。它們對混合類型的行為模擬了 Lua 中這些運算子的常見行為。如果您嘗試比較字串和數字的順序,Lua 會引發錯誤。類似地,如果您嘗試比較兩個具有不同順序元方法的物件,Lua 會引發錯誤。
等式比較絕不會引發錯誤,但如果兩個物件具有不同的元方法,則等式運算會導致 false,甚至不會呼叫任何元方法。同樣,此行為模擬了 Lua 的常見行為,它總是將字串分類為與數字不同,而不管它們的值如何。Lua 只有在兩個被比較物件共用此元方法時才會呼叫等式元方法。
版權所有 © 2003–2004 Roberto Ierusalimschy。保留所有權利。 | ![]() |