Kotlin 扩展
Kotlin 允许为已有类添加新函数(扩展函数)和属性(扩展属性)。
扩展函数
基本语法
// 为 String 添加扩展函数
fun String.addExclamation(): String {
return this + "!"
}
fun main() {
val str = "Hello"
println(str.addExclamation()) // Hello!
}
扩展函数原理
扩展函数实际上是静态方法的语法糖:
// Kotlin 扩展
fun String.addExclamation(): String = this + "!"
// 编译后的 Java 等价
public static String addExclamation(String receiver) {
return receiver + "!";
}
泛型扩展函数
T.EXTENSION
// 为所有类型添加通用扩展
fun <T> T.print(): T {
println(this)
return this
}
fun <T> T.describe(): String {
return "Value: $this"
}
fun main() {
42.print() // 42
"hello".describe() // Value: hello
}
可空接收者
// 为可空类型添加扩展
fun String?.orEmpty(): String {
return this ?: ""
}
fun main() {
val nullStr: String? = null
println(nullStr.orEmpty()) // 空字符串
val str: String = "Hello"
println(str.orEmpty()) // Hello
}
扩展属性
基本语法
// 为 String 添加扩展属性
val String.lastChar: Char
get() = this[length - 1]
// 可变扩展属性
var StringBuilder.lastChar: Char
get() = get(length - 1)
set(value) {
setCharAt(length - 1, value)
}
fun main() {
println("Hello".lastChar) // o
val sb = StringBuilder("Hello")
sb.lastChar = '!'
println(sb) // Hell!
}
扩展作用域
顶层扩展
// File: Extensions.kt
fun String.addPrefix(prefix: String): String {
return "$prefix$this"
}
// 在任何地方使用
fun main() {
println("World".addPrefix("Hello, ")) // Hello, World
}
类内扩展
class MyClass {
fun String.extension() {
// 可以访问 String 的成员
println("String: $this")
}
fun test() {
// 在类内部调用
"Hello".extension()
}
}
伴生对象扩展
class MyClass {
companion object
}
// 为伴生对象添加扩展
fun MyClass.Companion.create(): MyClass {
return MyClass()
}
fun main() {
val obj = MyClass.create()
}
扩展应用
可空类型扩展
// isNullOrEmpty 替代
fun <T : Any> T?.isNullOrEmpty(): Boolean {
return this == null || (this is Collection<*>) && this.isEmpty()
}
// 安全调用
fun <T> List<T>.secondOrNull(): T? {
return if (size >= 2) this[1] else null
}
常见扩展
// String 扩展
fun String.isEmail(): Boolean {
return contains("@") && contains(".")
}
fun String.toTitleCase(): String {
return split(" ").joinToString(" ") {
it.replaceFirstChar { c -> c.uppercase() }
}
}
// List 扩展
fun <T> List<T>.takeRandom(): T? {
return if (isEmpty()) null else random()
}
小结
本章我们学习了:
- 扩展函数:为已有类添加新函数
- 泛型扩展:为所有类型添加通用扩展
- 扩展属性:为已有类添加新属性
- 扩展作用域:顶层和类内扩展
- 伴生对象扩展:为伴生对象添加扩展
练习
- 为 Int 添加阶乘计算扩展函数
- 为 MutableList 添加 swap 函数
- 为 String 添加判断邮箱的扩展
- 创建自定义扩展库