Kotlin中首个操作数非自定义对象时如何重载运算符?
解决Kotlin中左操作数非自定义类时的运算符重载问题
嘿,这个场景我太熟悉了!刚用Kotlin写自定义数据类的时候,也踩过这个坑——默认在类内部定义的operator函数,只能处理当前类作为左操作数的情况,比如Vector2 + Vector2,但反过来或者左操作数是其他类型(比如数字)就会报错。不过别担心,用Kotlin的扩展函数就能完美解决这个问题!
先回顾类内的常规运算符重载
首先,咱们先看你可能已经写过的Vector2类内的重载,比如两个Vector2相加:
data class Vector2(val x: Double, val y: Double) { // 处理 Vector2 + Vector2 的情况 operator fun plus(other: Vector2): Vector2 { return Vector2(x + other.x, y + other.y) } // 同理,类内可以定义其他运算符,比如减、乘、除(针对Vector2之间的运算) operator fun minus(other: Vector2): Vector2 { return Vector2(x - other.x, y - other.y) } }
这种写法对两个Vector2的运算完全没问题,但如果想写5.0 + Vector2(1.0, 2.0)或者3 * Vector2(2.0, 3.0),编译器就会报错——因为Double/Int类里根本没有接受Vector2的plus/times方法。
用扩展函数实现左操作数为其他类型的运算符重载
这时候就需要给左操作数的类型写扩展运算符函数,比如针对Double、Int这些基础类型,扩展它们的运算符方法来支持和Vector2的运算:
示例1:支持 数字 + Vector2
// 扩展Double类,让它能和Vector2相加 operator fun Double.plus(v: Vector2): Vector2 { return Vector2(this + v.x, this + v.y) } // 扩展Int类,同样支持和Vector2相加 operator fun Int.plus(v: Vector2): Vector2 { return Vector2(this.toDouble() + v.x, this.toDouble() + v.y) }
现在5 + Vector2(1.0, 2.0)或者3.5 + Vector2(2.0, 3.0)就能正常编译运行了!
示例2:扩展其他运算符(减、乘、除)
按照同样的逻辑,我们可以给需要的类型扩展所有你需要的运算符:
// 支持 数字 - Vector2 operator fun Double.minus(v: Vector2): Vector2 { return Vector2(this - v.x, this - v.y) } // 支持 数字 * Vector2 operator fun Int.times(v: Vector2): Vector2 { return Vector2(this * v.x, this * v.y) } // 支持 Vector2 / 数字(这个可以写在类内,也可以写扩展) operator fun Vector2.div(scalar: Double): Vector2 { return Vector2(x / scalar, y / scalar) } // 如果需要支持 数字 / Vector2(注意数学合理性,按需实现) operator fun Double.div(v: Vector2): Vector2 { return Vector2(this / v.x, this / v.y) }
关键注意点
- 要确保你的运算逻辑符合数学常识或者业务需求,比如有些反向运算(比如数字除以Vector2)可能在你的场景里没有意义,那就没必要实现。
- 如果是其他自定义类型需要和Vector2运算,同样可以用这个方式:给那个自定义类型写对应的扩展运算符函数。
- 扩展函数可以放在和Vector2类同一个文件里,或者单独的扩展文件中,方便管理。
这样一来,不管左操作数是啥类型,只要你给它写了对应的扩展运算符,就能和Vector2进行+-*/等运算啦!
内容的提问来源于stack exchange,提问作者alexanders916
相关产品推荐
相关产品推荐

