kotlin必备常用重载运算符手册
算术运算符
+
运算符
+
运算符用于将两个值相加。在 Kotlin 中,您可以通过为您的类型定义名为 plus
的函数来支持 +
运算符。例如:
class Point(val x: Int, val y: Int) {
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}
val p1 = Point(1, 2)
val p2 = Point(3, 4)
val p3 = p1 + p2 // 使用 + 运算符计算两个点的和
在这个示例中,Point
类型实现了 plus
函数,以支持 +
运算符。当您使用 +
运算符将两个 Point
对象相加时,Kotlin 将调用 plus
函数来执行实际的添加操作。
-
运算符
-
运算符用于从一个值中减去另一个值。在 Kotlin 中,您可以通过为您的类型定义名为 minus
的函数来支持 -
运算符。例如:
class Point(val x: Int, val y: Int) {
operator fun minus(other: Point): Point {
return Point(x - other.x, y - other.y)
}
}
val p1 = Point(3, 4)
val p2 = Point(1, 2)
val p3 = p1 - p2 // 使用 - 运算符计算两个点之间的差
在这个示例中,Point
类型实现了 minus
函数,以支持 -
运算符。当您使用 -
运算符从一个 Point
对象中减去另一个 Point
对象时,Kotlin 将调用 minus
函数来执行实际的减法操作。
*
运算符
*
运算符用于将两个值相乘。在 Kotlin 中,您可以通过为您的类型定义名为 times
的函数来支持 *
运算符。例如:
class Point(val x: Int, val y: Int) {
operator fun times(scale: Double): Point {
return Point((x * scale).toInt(), (y * scale).toInt())
}
}
val p1 = Point(1, 2)
val p2 = p1 * 2.5 // 使用 * 运算符将点的坐标乘以一个因子
在这个示例中,Point
类型实现了 times
函数,以支持 *
运算符。当您使用 *
运算符将一个 Point
对象乘以一个因子时,Kotlin 将调用 times
函数来执行实际的乘法操作。
/
运算符
/
运算符用于将一个值除以另一个值。在 Kotlin 中,您可以通过为您的类型定义名为 div
的函数来支持 /
运算符。例如:
class Point(val x: Int, val y: Int) {
operator fun div(scale: Double): Point {
return Point((x / scale).toInt(), (y / scale).toInt())
}
}
val p1 = Point(10, 20)
val p2 = p1 / 2.5 // 使用 / 运算符将点的坐标除以一个因子
在这个示例中,Point
类型实现了 div
函数,以支持 /
运算符。当您使用 /
运算符将一个 Point
对象除以一个因子时,Kotlin 将调用 div
函数来执行实际的除法操作。
比较运算符
==
和 !=
运算符
==
和 !=
运算符用于比较两个值是否相等。在 Kotlin 中,您可以通过为您的类型定义名为 equals
的函数来支持 ==
和 !=
运算符。Kotlin 还会为您自动生成 equals
函数和 hashCode
函数。例如:
class Point(val x: Int, val y: Int) {
operator fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Point) return false
return x == other.x && y == other.y
}
}
val p1 = Point(1, 2)
val p2 = Point(1, 2)
val p3 = Point(3, 4)
p1 == p2 // true,因为 p1 和 p2 的坐标相同
p1 != p3 // true,因为 p1 和 p3 的坐标不同
在这个示例中,Point
类型实现了 equals
函数,以支持 ==
和 !=
运算符。当您使用 ==
或 !=
运算符比较两个 Point
对象时,Kotlin 将调用 equals
函数来执行实际的比较操作。
需要注意的是,在实现 equals
函数时,您应该按照约定遵循以下几个规则:
- 自反性:对于任何非空引用值
x
,x.equals(x)
应该返回true
。 - 对称性:对于任何非空引用值
x
和y
,如果x.equals(y)
返回true
,那么y.equals(x)
也应该返回true
。 - 传递性:对于任何非空引用值
x
、y
和z
,如果x.equals(y)
返回true
,且y.equals(z)
也返回true
,那么x.equals(z)
也应该返回true
。 - 一致性:对于任何非空引用值
x
和y
,只要对象上所用的信息没有被修改,多次调用x.equals(y)
应该始终返回相同的结果。 - 非空性:对于任何非空引用值
x
,x.equals(null)
应该返回false
。
<
、<=
、>
和 >=
运算符
<
、<=
、>
和 >=
运算符用于比较两个值的大小关系。在 Kotlin 中,您可以通过为您的类型定义名为 compareTo
的函数来支持这些运算符。例如:
class Point(val x: Int, val y: Int) : Comparable<Point> {
override operator fun compareTo(other: Point): Int {
return compareValuesBy(this, other, { it.x }, { it.y })
}
}
val p1 = Point(1, 2)
val p2 = Point(3, 4)
p1 < p2 // true,因为 p1 的坐标小于 p2 的坐标
在这个示例中,Point
类型实现了 compareTo
函数,并实现了 Comparable<Point>
接口,以支持比较运算符。当您使用 <
、<=
、>
和 >=
运算符比较两个 Point
对象时,Kotlin 将调用 compareTo
函数来执行实际的比较操作。
需要注意的是,在实现 compareTo
函数时,您应该确保其满足一些约定:
- 返回值为负数表示当前对象小于比较对象。
- 返回值为零表示当前对象等于比较对象。
- 返回值为正数表示当前对象大于比较对象。
区间运算符
..
运算符
..
运算符用于表示一个区间范围。在 Kotlin 中,您可以通过为您的类型定义名为 rangeTo
的函数来支持 ..
运算符。例如:
class Date(val year: Int, val month: Int, val day: Int) {
operator fun rangeTo(other: Date): DateRange {
return DateRange(this, other)
}
}
class DateRange(val start: Date, val endInclusive: Date) : Iterable<Date> {
override fun iterator(): Iterator<Date> {
return object : Iterator<Date> {
var current = start
override fun hasNext() = current <= endInclusive
override fun next(): Date {
val next = current
current = current.nextDay()
return next
}
}
}
private fun Date.nextDay(): Date {
// 计算日期的下一天
}
}
val startDate = Date(2022, 1, 1)
val endDate = Date(2022, 1, 31)
val dates = startDate..endDate // 使用 .. 运算符创建一个日期范围
for (date in dates) {
println(date) // 输出该日期范围内的所有日期
}
在这个示例中,Date
类型实现了 rangeTo
函数,以支持 ..
运算符。当您使用 ..
运算符创建一个日期范围时,Kotlin 将调用 rangeTo
函数来创建实际的范围对象。由于范围对象实现了 Iterable
接口,因此可以通过在 for
循环中迭代范围内的值来输出它们。
需要注意的是,在实现 rangeTo
函数时,您应该确保其返回一个实现了 Iterable
接口的对象,并且该对象应支持使用 for
循环遍历范围内的所有值。
in
运算符
in
运算符用于检查一个值是否位于某个区间内。在 Kotlin 中,区间对象实现了 ClosedRange<T>
接口,该接口定义了一个名为 contains
的函数,用于检查一个值是否位于该区间内。例如:
class Date(val year: Int, val month: Int, val day: Int) : Comparable<Date> {
override operator fun compareTo(other: Date): Int {
// 比较两个日期的大小
}
}
val startDate = Date(2022, 1, 1)
val endDate = Date(2022, 1, 31)
val currentDate = Date(2022, 1, 15)
currentDate in startDate..endDate // true,因为当前日期处于该区间内
在这个示例中,startDate..endDate
使用 ..
运算符创建了一个 Date
类型的区间对象。当您使用 in
运算符检查某个日期是否位于该区间内时,Kotlin 将调用 contains
函数来执行实际的检查操作。
需要注意的是,在实现 contains
函数时,您应该确保其满足以下约定:
- 函数参数应为一个与区间元素类型相同的值,并返回一个布尔值,指示该值是否位于区间内。
- 区间对象应实现
ClosedRange<T>
接口,并且应确保在包含起始和结束元素的情况下遵循闭合区间或半开区间的规则。
until
运算符
until
运算符用于表示一个半开区间,即不包含结束元素的区间范围。在 Kotlin 中,您可以通过为您的类型定义名为 rangeTo
的函数来支持 until
运算符。例如:
class Date(val year: Int, val month: Int, val day: Int) {
operator fun rangeTo(other: Date): DateRange {
return DateRange(this, other)
}
}
class DateRange(val start: Date, val endExclusive: Date) : Iterable<Date> {
override fun iterator(): Iterator<Date> {
return object : Iterator<Date> {
var current = start
override fun hasNext() = current < endExclusive
override fun next(): Date {
val next = current
current = current.nextDay()
return next
}
}
}
private fun Date.nextDay(): Date {
// 计算日期的下一天
}
}
val startDate = Date(2022, 1, 1)
val endDate = Date(2022, 2, 1)
val dates = startDate until endDate // 使用 until 运算符创建一个日期范围
for (date in dates) {
println(date) // 输出该日期范围内的所有日期,不包括结束日期
}
在这个示例中,Date
类型实现了 rangeTo
函数,以支持 until
运算符。当您使用 until
运算符创建一个日期范围时,Kotlin 将调用 rangeTo
函数来创建实际的范围对象。由于范围对象实现了 Iterable
接口,因此可以通过在 for
循环中迭代范围内的值来输出它们。
需要注意的是,在实现 rangeTo
函数时,您应该确保其返回一个实现了 Iterable
接口的对象,并且该对象应支持使用 for
循环遍历半开区间内的所有值。
其他运算符
in
和 !in
运算符
in
运算符用于检查一个值是否属于一个集合、数组或区间等对象。在 Kotlin 中,您可以通过为您的类型定义名为 contains
的函数来支持 in
运算符。例如:
class Point(val x: Int, val y: Int) {
operator fun contains(other: Point): Boolean {
return x == other.x && y == other.y
}
}
val p1 = Point(1, 2)
val p2 = Point(3, 4)
val points = listOf(p1, p2)
p1 in points // true,因为点 p1 在列表中
p2 !in points // false,因为点 p2 不在列表中
在这个示例中,Point
类型实现了 contains
函数,以支持 in
运算符。当您使用 in
或 !in
运算符检查某个 Point
对象是否属于一个列表时,Kotlin 将调用 contains
函数来执行实际的检查操作。
需要注意的是,在实现 contains
函数时,您应该确保其满足一些约定:
- 当您的类型是一个集合或者数组时,
contains
函数应该接受一个参数,表示要检查的元素,并返回一个布尔值,指示该元素是否属于该集合或数组。 - 当您的类型是一个区间或者带有
Comparable
接口实现的对象时,contains
函数应该接受一个参数,表示要检查的值,并返回一个布尔值,指示该值是否位于该区间或者对象的值范围内。
+=
、-=
、*=
和 /=
运算符
+=
、-=
、*=
和 /=
运算符用于对一个可变对象(如列表或者数组)进行修改操作。在 Kotlin 中,您可以通过为您的类型定义名为 plusAssign
、minusAssign
、timesAssign
和 divAssign
的函数来支持这些运算符。例如:
class Point(var x: Int, var y: Int) {
operator fun plusAssign(other: Point) {
x += other.x
y += other.y
}
}
var p1 = Point(1, 2)
val p2 = Point(3, 4)
p1 += p2 // 使用 += 运算符将点 p2 加到点 p1 上
在这个示例中,Point
类型实现了 plusAssign
函数,以支持 +=
运算符。当您使用 +=
、-=
、*=
和 /=
运算符对一个可变对象进行修改时,Kotlin 将调用 plusAssign
、minusAssign
、timesAssign
和 divAssign
函数来执行实际的修改操作。
需要注意的是,在实现 plusAssign
、minusAssign
、timesAssign
和 divAssign
函数时,您应该确保其满足以下约定:
- 函数参数必须为可变对象。
- 函数不应返回任何值。
- 在完成修改操作后,对象的状态应该反映出修改后的结果。
is
运算符
is
运算符用于检查一个对象是否为某个类型或者其子类型。在 Kotlin 中,您可以通过为您的类型定义名为 isInstance
的函数来支持 is
运算符。例如:
open class Animal
class Cat : Animal()
val animal = Cat()
if (animal is Cat) {
// 如果动物是一只猫,则执行以下操作
}
在这个示例中,Cat
类型是 Animal
类型的子类型。当您使用 is
运算符检查某个动物是否为猫时,Kotlin 将调用 isInstance
函数来执行实际的检查操作。
需要注意的是,在实现 isInstance
函数时,您应该确保其满足以下约定:
- 函数参数应为一个
Any?
类型的值,并返回一个布尔值,指示该值是否为当前类型或者其子类型的实例。 - 当您为一个类定义
isInstance
函数时,应将其定义为一个companion object
中的扩展函数,以确保该函数可以作为is
运算符的一部分使用而无需创建实例。