扩展属性
例如,给 Float 扩展一个 int 属性:
1 2 3 4
| val Float.int get() = this.toInt() val test = 13.0f.int
|
扩展函数
使用
1 2 3 4 5 6 7 8 9 10
| package com.xl.test
fun Int.formatString(format: String): String { return String.format(format, this) }
printlin(4.formatString("current value = %d"))
current value = 4
|
- 扩展函数属于谁?属于函数左边的类吗?并不是,这里的扩展函数是一个顶层的,它谁也不属于,它只属于它所在的 package。
- 为什么可以被这个类调用呢?因为我们在这个函数限定了一个 Receiver,也就是函数左边的那个类。
作用域
扩展函数可以写在方法,类,顶层中,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| //方法 fun test() { //...
fun Int.formatString(format: String): String { return String.format(format, this) } }
//类 class Func { fun Int.formatString(format: String): String { return String.format(format, this) } }
//顶层 package com.xl.test
fun Int.formatString(format: String): String { return String.format(format, this) }
|
扩展函数的引用
普通的成员函数怎么引用:类名::函数名,扩展函数呢?它的类名到底写什么呢?
- 针对写在顶层的扩展函数,它的类名直接写 Receiver 的类名即可。
- 针对写在类中等其他扩展函数,它的类名是写坐在类的类名还是写 Receiver 的类名呢?这是有歧义的,所以 Kotlin 不允许我们引用。
跟普通函数的引用一样,扩展函数的引用也可以被调用,直接调用或者用 invoke() 都可以,不过要记得把 Receiver 也就是接收者或者说调用者填成第一个参数:
1 2 3 4 5 6 7 8 9 10
| fun String.method(length: Int) { }
val temp: String.(Int) -> Unit = String::method
"test".temp(3) temp("test", 3) temp.invole("test", 3)
|
有无 Receiver 的变量的互换:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| fun String.method1(length: Int) { println("size = ${this.length}, length = $length") }
fun method2(text: String, length: Int) { println("size = ${text.length}, length = $length") }
val a: String.(Int) -> Unit = String::method1 val b: (String, Int) -> Unit = String::method1
val c: (String, Int) -> Unit = ::method2 val d: String.(Int) -> Unit = ::method2
"test".a(3) b("test", 3)
c("test", 3) "test".d(3)
|