前言
之前虽然了解操作符,但是一直对操作符重载有点懵,今天重新梳理了一下,其实很简单
什么是操作符
Kotlin 允许我们为自己的类型提供预定义的一组操作符的实现。这些操作符具有固定的符号表示 (如
+
或*
)和固定的优先级。为实现这样的操作符,我们为相应的类型(即二元操作符左侧的类型和一元操作符的参数类型)提供了一个固定名字的成员函数或扩展函数。 重载操作符的函数需要用operator
修饰符标记。
这个问题官网和Kotlin中文都有,博客也很多,可以先看下:
Kotlin中文网:https://www.kotlincn.net/docs/reference/operator-overloading.html
做一点白话补充:
其实操作符就是Kotlin内置了一堆符号与操作的映射,举个例子就明白了:
1 + 2
,在Kotlin中,这个+
号其实就是1.plus(2)
,那么这个plus就是内置的操作符,而我们使用时可以直接1.plus(2)
也可以用1 + 2
,类似还有compareTo等等。。。
内置的操作符重载
基本数据类型的操作符在Primitives.kt
源码中;
内置的操作符重载其实有很多,举个例子:
public abstract class AbstractMap<K, out V> protected constructor() : Map<K, V> {
override operator fun get(key: K): V? = implFindEntry(key)?.value
}
Kotlin中的Map集合,重载了get
操作符之后,使得我们在根据key来获取Value时,不光可以用hashMap.get(key),也可以使用hashMap[key];
还有类似的,我们在使用协程时,经常看到public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)这样的代码,其实就是重载了操作符plus:
public interface CoroutineContext {
public operator fun plus(context: CoroutineContext): CoroutineContext =
if (context === EmptyCoroutineContext) this else // fast path -- avoid lambda creation
context.fold(this) { acc, element ->
val removed = acc.minusKey(element.key)
if (removed === EmptyCoroutineContext) element else {
// make sure interceptor is always last in the context (and thus is fast to get when present)
val interceptor = removed[ContinuationInterceptor]
if (interceptor == null) CombinedContext(removed, element) else {
val left = removed.minusKey(ContinuationInterceptor)
if (left === EmptyCoroutineContext) CombinedContext(element, interceptor) else
CombinedContext(CombinedContext(left, element), interceptor)
}
}
}
}
自定义操作符重载
任何一个对象都可以进行操作符重载,使用operator关键字之后,Android Studio就会提示可以重载哪些操作符,所以不需要去记;
operator.png
class Person(var name: String)
operator fun Person.plus(p: Person): Person {
this.name += p.name
return this
}
调用:(Person("1") + Person("2")).name.logI()
输出:com.wei.sample I/shuxin.wei: 12
总结
其实操作符重载很简单,目的就是让我重写一些简单操作,在编码过程中用符号来代替,例如用+代替plus方法;仅此而已。
网友评论