扩展函数
声明一个扩展函数,我们需要用一个 接收者类型 也就是被扩展的类型来作为他的前缀。
package foo.bar;
infix fun Int.ride(num: Int): Int{
println("num= $num")
return 2 * num
}
open class A{
open fun testSwap(mutableList: MutableList<Int>){
mutableList.swap(0, 2)
}
open fun MutableList<Int>.swap(index1: Int, index2: Int){
var temp = this[index1]
this[index1] = this[index2]
this[index2] = temp
println(this)
}
}
package foo.bar;
object MyTest {
@JvmStatic
fun main(arg: Array<String>) {
println("test_kotlin")
A().testSwap(mutableListOf(1, 2, 3))
}
}
输出结果:
[3, 2, 1]
扩展函数接收者类型可以为 null
fun Any?.toString(): String {
if (this == null) return "null"
// 空检测之后,“this”会自动转换为非空类型,所以下面的 toString()
// 解析为 Any 类的成员函数
return toString()
}
扩展的作用域
大多数时候我们在顶层定义扩展,即直接在包里:
package foo.bar; //将扩展方法放到包内,作用域将是整个包
infix fun Int.ride(num: Int): Int{
println("num= $num")
return 2 * num
}
import foo.bar.* //使用时需要导包
object MyTest {
@JvmStatic
fun main(arg: Array<String>) {
println(3.ride(2))
}
}
打印结果:
6
中缀表示法
标有 infix 关键字的函数也可以使用中缀表示法(忽略该调用的点与圆括号)调用。中缀函数必须满足以下要求:
上面代码可简写为:println(3 ride 2)
package foo.bar; //将扩展方法放到包内,作用域将是整个包
infix fun Int.ride(num: Int): Int{
println("num= $num")
return 2 * num
}
import foo.bar.* //使用时需要导包
object MyTest {
@JvmStatic
fun main(arg: Array<String>) {
println(3 ride 2)
}
}
打印结果:
6
注意:
中缀函数调用的优先级低于算术操作符、类型转换以及 rangeTo
操作符。 以下表达式是等价的:
3 ride 2 + 3
与3 ride (2 + 3)
另一方面,中缀函数调用的优先级高于布尔操作符 &&
与 ||
、is-
与 in-
检测以及其他一些操作符。这些表达式也是等价的:
a && 1 ride 2
与a && (1 ride 2)
1 ride 2 in a
与(1 xor 2) in a
完整的优先级层次结构请参见其语法参考。