扩展函数
- 在Kotlin中我们可以完全自由扩展任何类的方法和属性,在不修改原类的情况下,Kotlin能给一个类扩展新功能而无需继承该类
eg:
/**
* 给String扩展一个firstChar函数
*/
fun String.firstChar(): String {
if (this.length == 0) {
return ""
}
return this[0].toString()
}
/**
* 给String扩展一个lastChar函数
*/
fun String.lastChar(): String {
if (this.length == 0) {
return ""
}
return this[this.length - 1].toString()
}
/**
* 给List添加一个filter方法
*/
fun <T> List<T>.mFilter(predicate: (T) -> Boolean): MutableList<T> {
val result = ArrayList<T>().apply {
this@mFilter.forEach { // 使用限定符原因:this指的是函数调用者,this关键字默认指向当前代码最内层,所以如果不加就相当于一致操作result数组,一直返回空,所以加上限定符指定范围
if (predicate(it)) {
add(it)
}
}
}
return result
}
@Test
fun testFun() {
val s = "ABC"
println(s.firstChar()) // A
println(s.lastChar()) // C
val list = mutableListOf(1, 2, 3, 4, 5)
val result = list.mFilter{it % 2 == 1}
println(result)
}
-
注意:
- 如果在别的package下使用,需要导入扩展函数
-
扩展语法说明
扩展属性
eg:
var <T> MutableList<T>.firstElement: T
get() {
return this[0]
}
set(value) {
this[0] = value
}
var <T> MutableList<T>.lastElement: T
get() {
return this[this.size - 1]
}
set(value) {
this[this.size - 1] = value
}
@Test
fun testFun() {
val mutablelist = mutableListOf(1,2,3,4,5,6,7)
println(mutablelist.firstElement) // 1
println(mutablelist.lastElement) // 7
mutablelist.firstElement = 0
mutablelist.lastElement = 9
println(mutablelist.firstElement) // 0
println(mutablelist.lastElement) // 9
}
-
注意 :
- 扩展属性允许定义在类或者Kotlin文件中,不允许定义在函数中
-
扩展属性语法说明
扩展实现原理
- 扩展属性和扩展函数本质是以静态导入的方式实现的,可以通过Kotlin的ByteCode来理解,firstChar方法反编译成Java代码如下
@NotNull
public final String firstChar(@NotNull String $this$firstChar) {
Intrinsics.checkParameterIsNotNull($this$firstChar, "$this$firstChar");
return $this$firstChar.length() == 0 ? "" : String.valueOf($this$firstChar.charAt(0));
}
扩展中的this关键字
- 扩展的filter函数中用到了this关键字
this.forEach {
if (predicate(it) {
result.add(it)
}
}
- 这里的this指的是接收者对象,即函数的调用对象实例,为了表示当前函数的接收者,kotlin使用this表达式,但是需要注意以下几点:
- 在类成员函数中,this指向这个类的当前对象实例
- 在扩展函数中,或带接收者的函数的字面值中,this代表调用函数时,在点号左侧传递的接收者参数
- 如果this没有限定符,那么它默认指向当前代码最内层的范围,可以使用限定符限定范围