# 元表与元方法

URL: https://caijiao.org/lua/metatable
Source: docs/lua/metatable.md
Description: 学习 Lua 的元表（Metatable）和元方法（Metamethod），实现运算符重载、面向对象及自定义行为。

Lua 的 **元表（Metatable）** 是表的元信息，它允许你 **自定义表的行为**，如重载运算符、改变索引访问、控制方法调用等。元表中的特殊函数称为 **元方法（Metamethod）**。

## 🧩 基本用法

```lua
local t = {}
local mt = {}

setmetatable(t, mt)
````

> `setmetatable(table, metatable)` 将元表关联到目标表。

## 🔗 __index 元方法

当访问表中不存在的字段时，会触发 `__index`。

```lua
local t = {}
local mt = {
  __index = function(table, key)
    return key .. " 不存在"
  end
}

setmetatable(t, mt)

print(t.name)  -- 输出：name 不存在
```

> `__index` 也可以是另一个表，实现类似继承。

## ➕ 运算符重载

Lua 支持通过元方法重载运算符，如 `+`、`-`、`*`、`..` 等。

```lua
local t1 = {x = 1, y = 2}
local t2 = {x = 3, y = 4}

local mt = {
  __add = function(a, b)
    return { x = a.x + b.x, y = a.y + b.y }
  end
}

setmetatable(t1, mt)
setmetatable(t2, mt)

local t3 = t1 + t2
print(t3.x, t3.y)  -- 输出 4 6
```

## 🧱 __tostring 元方法

自定义表的字符串表示：

```lua
local t = {x = 10, y = 20}
local mt = {
  __tostring = function(tbl)
    return "(" .. tbl.x .. "," .. tbl.y .. ")"
  end
}
setmetatable(t, mt)

print(t)  -- 输出：(10,20)
```

## 🧩 面向对象示例

```lua
local Person = {}
Person.__index = Person

function Person:new(name, age)
  local obj = {name = name, age = age}
  setmetatable(obj, self)
  return obj
end

function Person:greet()
  print("Hello, " .. self.name)
end

local p = Person:new("Alice", 20)
p:greet()  -- 输出：Hello, Alice
```

> 元表配合 `__index` 可实现简单的面向对象机制。

## 🧠 小结

* 元表（Metatable）定义表的元行为
* 常用元方法：`__index`、`__newindex`、`__add`、`__tostring` 等
* 可实现运算符重载、继承和面向对象
* Lua 的高级技巧很多都依赖元表实现
