二十二)Kotlin简单易学 基础语法-定义扩展函数
定义扩展函数
扩展可以在不直接修改类定义的情况下增加类功能,扩展可以用于自定义类,也可用于比如List,String以及Kotlin标准库里的其他类。和继承相似,扩展也能共享类行为,在你无法接触某个类定义,或者某个类没有使用open修饰符,导致你无法继承它时,扩展就是增加类功能的最好选择。
String 扩展
//追加!!
fun String.ddExt(amount: Int = 1) = run { this + "!".repeat(amount) }
fun main() {
//輸出abv!!
println("abv".ddExt(3))
}
超类扩展
fun Any.easyPrint() = print((this))
"abv".easyPrint()
定义扩展函数
定义扩展函数和定义一般函数差不多,但有一点不一样,除了函数定义,你还需要指定接受功能扩展的接收者类型。
泛型扩展函数
新的泛型扩展函数不仅可以支持任何类型的接收者,还保留了接受者的类型信息,使用泛型类型后,扩展函数能够支持更多类型的接受者,使用范围更广了。
//追加!!
fun String.ddExt(amount: Int = 1) = run { this + "!".repeat(amount) }
fun <T> T.easyPrint(): T {
println(this)
return this
}
fun main() {
"abc".easyPrint().ddExt(2)
}
扩展属性
除了给类添加功能扩展函数外,你还可以给类定义扩展属性,给String类添加一个扩展,这个扩展属性可以统计字符串有多少个元音字母。
val String.numVowels
get() = count { "aeiou".contains(it) }
fun <T> T.easyPrint(): T {
println(this)
return this
}
fun main() {
"abc".numVowels.easyPrint()
}
可空类扩展
你也可以扩展函数用于可空类型,在可空类型上定义扩展函数,你就可以直接在扩展函数体内解决可能出现的空值问题。
fun String?.printWithDefault(default:String)= print(this ?:default)
fun main() {
val nullableString:String?= null
nullableString.printWithDefault("abc")
}
infix关键字
infix关键字适用于有单个参数的扩展和类函数,可以让你以更简洁的语法调用函数,如果一个函数定义使用了infix关键字,那么调用它时,接收者和函数之间的点操作以及参数的一对括号都可以不要。
infix fun String?.printWithDefault(default:String)= print(this ?:default)
fun main() {
val nullableString:String?= null
//收者和函数之间的点操作以及参数的一对括号都可以不要
nullableString printWithDefault "abc"
}
定义扩展文件
扩展函数需要在多个文件里面使用,可以将它定义在单独的文件,然后import。
fun <T> Iterable<T>.randomTake(): T = this.shuffled().first()
import randomTake
fun main() {
val list = listOf("Jaso", "jack")
list.randomTake()
}
重命名扩展
有时候,你想使用一个扩展或一个类,但它的名字不和你的意。
//有时候,你想使用一个扩展或一个类,但它的名字不和你的意。 as ramdomizer
import randomTake as ramdomizer
fun main() {
val list = listOf("Jaso", "jack")
list.ramdomizer()
}
Kotlin标准库中的扩展
Kotlin标准库的很多功能都是通过扩展函数和扩展属性来实现的,包含类扩展的标准库文件通常都是以类名加s后缀来命名的,例如Sequences.kt, Ranfes.kt,Maps.kt。
带接受者的函数字面量
apply函数是如何做到支持接收者对象的隐式调用的。
public inline fun<T> T.apply(block:T.()->Unit):T{block() return this}