跳到主要内容

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()
}

小结

本章我们学习了:

  1. 扩展函数:为已有类添加新函数
  2. 泛型扩展:为所有类型添加通用扩展
  3. 扩展属性:为已有类添加新属性
  4. 扩展作用域:顶层和类内扩展
  5. 伴生对象扩展:为伴生对象添加扩展

练习

  1. 为 Int 添加阶乘计算扩展函数
  2. 为 MutableList 添加 swap 函数
  3. 为 String 添加判断邮箱的扩展
  4. 创建自定义扩展库