元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
Lua语言基础
▶
环境搭建
安装Lua解释器
配置开发环境
第一个Lua程序
▶
基本语法
变量与数据类型
运算符与表达式
控制结构
▶
数据结构
表(Table)详解
数组与迭代
字符串处理
▶
Lua高级编程
▶
函数编程
函数定义与调用
闭包与作用域
高阶函数应用
▶
元表与元方法
元表基础
操作符重载
继承与对象系统
▶
协程编程
协程基础
生产者-消费者模式
协程调度实践
▶
Lua应用实践
▶
游戏开发
Lua与游戏引擎集成
AI脚本实现
热更新机制
▶
系统编程
Lua与C交互
扩展库开发
性能优化技巧
▶
实用工具开发
配置文件解析
自动化测试框架
网络编程基础
发布时间:
2025-03-24 12:10
↑
☰
wen z# Lua操作符重载 本文将介绍如何在Lua中使用元表来实现操作符重载,让你能够为自定义类型定义各种运算符的行为。 ## 操作符重载基础 在Lua中,我们使用元表(metatable)中的特殊字段(元方法)来实现操作符重载: ```lua -- 基本结构 local MyClass = {} MyClass.__index = MyClass function MyClass.new(value) return setmetatable({value = value}, MyClass) end -- 重载加法运算符 function MyClass.__add(a, b) return MyClass.new(a.value + b.value) end -- 使用示例 local a = MyClass.new(10) local b = MyClass.new(20) local c = a + b -- 调用__add元方法 print(c.value) -- 输出:30 ``` ## 算术运算符重载 ### 1. 基本算术运算符 ```lua -- 定义一个复数类 local Complex = {} Complex.__index = Complex function Complex.new(real, imag) return setmetatable({real = real, imag = imag}, Complex) end -- 加法 function Complex.__add(a, b) return Complex.new(a.real + b.real, a.imag + b.imag) end -- 减法 function Complex.__sub(a, b) return Complex.new(a.real - b.real, a.imag - b.imag) end -- 乘法 function Complex.__mul(a, b) return Complex.new( a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real ) end -- 除法 function Complex.__div(a, b) local denom = b.real * b.real + b.imag * b.imag return Complex.new( (a.real * b.real + a.imag * b.imag) / denom, (a.imag * b.real - a.real * b.imag) / denom ) end -- 一元减法 function Complex.__unm(a) return Complex.new(-a.real, -a.imag) end -- 使用示例 local c1 = Complex.new(1, 2) -- 1 + 2i local c2 = Complex.new(3, 4) -- 3 + 4i local sum = c1 + c2 local diff = c1 - c2 local prod = c1 * c2 local quot = c1 / c2 local neg = -c1 ``` ### 2. 幂运算符 ```lua -- 实现幂运算 function Complex.__pow(a, n) if type(n) ~= "number" then error("指数必须是数字") end local result = Complex.new(1, 0) for i = 1, n do result = result * a end return result end -- 使用示例 local c = Complex.new(1, 1) -- 1 + i local squared = c ^ 2 -- (1 + i)² ``` ## 关系运算符重载 ### 1. 相等性比较 ```lua -- 定义一个向量类 local Vector = {} Vector.__index = Vector function Vector.new(x, y) return setmetatable({x = x, y = y}, Vector) end -- 相等比较 function Vector.__eq(a, b) return a.x == b.x and a.y == b.y end -- 小于比较 function Vector.__lt(a, b) return a:length() < b:length() end -- 小于等于比较 function Vector.__le(a, b) return a:length() <= b:length() end function Vector:length() return math.sqrt(self.x * self.x + self.y * self.y) end -- 使用示例 local v1 = Vector.new(3, 4) local v2 = Vector.new(3, 4) local v3 = Vector.new(5, 12) print(v1 == v2) -- true(相同坐标) print(v1 < v3) -- true(v1的长度小于v3) print(v1 <= v2) -- true(长度相等) ``` ## 其他运算符重载 ### 1. 字符串转换 ```lua -- 为复数类添加字符串表示 function Complex.__tostring(c) if c.imag >= 0 then return string.format("%.2f + %.2fi", c.real, c.imag) else return string.format("%.2f - %.2fi", c.real, -c.imag) end end -- 使用示例 local c = Complex.new(1.5, -2.3) print(c) -- 输出:1.50 - 2.30i ``` ### 2. 连接运算符 ```lua -- 定义一个列表类 local List = {} List.__index = List function List.new(...) return setmetatable({...}, List) end -- 重载连接运算符 function List.__concat(a, b) local result = List.new() -- 复制第一个列表的元素 for i = 1, #a do result[i] = a[i] end -- 添加第二个列表的元素 for i = 1, #b do result[#result + 1] = b[i] end return result end -- 字符串表示 function List.__tostring(list) local items = {} for i = 1, #list do items[i] = tostring(list[i]) end return "[" .. table.concat(items, ", ") .. "]" end -- 使用示例 local list1 = List.new(1, 2, 3) local list2 = List.new(4, 5, 6) local combined = list1 .. list2 print(combined) -- 输出:[1, 2, 3, 4, 5, 6] ``` ### 3. 调用语法 ```lua -- 定义一个函数对象类 local Function = {} Function.__index = Function function Function.new(func) return setmetatable({func = func}, Function) end -- 重载函数调用语法 function Function.__call(...) local self = table.remove(arg, 1) return self.func(unpack(arg)) end -- 使用示例 local add = Function.new(function(a, b) return a + b end) print(add(10, 20)) -- 输出:30 ``` ## 常见问题解答 ### Q1: 为什么需要操作符重载? 操作符重载可以让我们: - 为自定义类型提供直观的操作语法 - 使代码更简洁易读 - 实现领域特定的运算规则 ### Q2: 哪些运算符可以重载? Lua支持重载以下运算符: - 算术运算符:+, -, *, /, %, ^, -(一元) - 关系运算符:==, ~=, <, <=, >, >= - 连接运算符:.. - 长度运算符:# - 调用语法:() ### Q3: 如何处理类型不匹配的情况? ```lua -- 类型检查示例 function Vector.__add(a, b) if type(a) ~= "table" or type(b) ~= "table" then error("操作数必须是向量") end return Vector.new(a.x + b.x, a.y + b.y) end ``` ## 下一步 现在你已经掌握了Lua的操作符重载,可以继续学习[继承与对象系统](/article/lua/advanced/oop)来了解如何构建完整的面向对象系统。 ## 参考资源 - [Lua 5.4 参考手册 - 元方法](http://www.lua.org/manual/5.4/manual.html#2.4) - [Programming in Lua - 操作符重载](http://www.lua.org/pil/13.html) - [Lua设计模式](http://lua-users.org/wiki/ObjectOrientedProgramming)