元表与元方法
元表
Lua中的每个值都有一个元表。table和userdata可以有各自独立的元表,而其他类型的值则共享类型所属的单一元表。Lua在创建新的table时不会创建元表。
使用setmetatable来设置或修改任何table的元表。
1 | t = {} |
任何table都可以作为任何值的元表,而一组相关的table也可以共享一个通用的元表,此元表描述了它们共同的行为。
Lua代码中,只能设置table的元表。若要设置其他类型的值的元表,则必须通过C代码来完成。
下面示例用来说明如何使用元表。
1 | set = {} |
1 | function Set.union(a, b) |
1 | function Set.intersection(a, b) |
1 | function Set.tostring(set) |
1 | mt.__le = function(a, b) |
1 | mt.__lt = function(a, b) |
1 | mt.__eq = function(a, b) |
1 | mt.__add = Set.union |
1 | s1 = Set.new{2, 4} |
在元表中,每种算术操作符都有对应的字段名。
- __add(+) –> 加法
- __mul(*) –> 乘法
- __sub(减法) –> 减法
- __div(除法) –> 除法
- __unm(相反数)
- __mod(取模)
- __pow(乘幂)
- __concat(描述连接操作符的行为)
- __le(<=) –> 子集
- __lt(<) –> 真子集
- __eq(==) –> 相等
- __len –> 长度
- __index –> 索引查询
- __newindex –> 索引更新
###table访问的元方法
####__index元方法
当访问一个table中不存在的字段时,这些访问会促使解释器去寻找一个叫__index的元方法,如果没有这个元方法,那么访问结果为nil。否则,就由这个元方法来提供最终结果。
下面将介绍一个有关继承的典型示例。
1 | Window = {} -- 创建一个名字空间 |
1 | Window.mt.__index = function(table, key) |
1 | w = Window.new{x=10, y=20} |
下面通过__index元方法实现一个具有默认值的table
1 | function setDefault (t, d) |
1 | tab = {x=10, y=20} |