当前位置: 首页 > news >正文

Kotlin扩展函数与属性

扩展函数和属性是Kotlin中最具特色的功能之一,它们允许我们在不修改原有类的情况下为类添加新功能。这种设计既保持了类的封装性,又提供了强大的扩展能力。

一、扩展函数:为现有类添加新行为

1.1 基础扩展函数
扩展函数允许我们为任何类(包括Java类)添加新方法:

// 为String类添加扩展函数
fun String.addExclamation(): String {return "$this!"
}// 为Int添加平方计算
fun Int.square(): Int {return this * this
}fun main() {val greeting = "Hello"println(greeting.addExclamation()) // 输出: Hello!val number = 5println(number.square()) // 输出: 25
}

1.2 实用扩展函数示例
1.2.1 集合操作扩展

// 安全获取元素,越界时返回null
fun <T> List<T>.getSafe(index: Int): T? {return if (index in indices) get(index) else null
}// 统计满足条件的元素数量
fun <T> Iterable<T>.countBy(predicate: (T) -> Boolean): Int {return count(predicate)
}fun main() {val list = listOf("Apple", "Banana", "Cherry")println(list.getSafe(1)) // 输出: Bananaprintln(list.getSafe(5)) // 输出: nullval count = list.countBy { it.length > 5 }println("长度>5的单词数: $count") // 输出: 2
}

1.2.2 日期时间处理扩展

// 计算两个日期之间的天数
fun LocalDate.daysUntil(other: LocalDate): Long {return ChronoUnit.DAYS.between(this, other)
}// 判断是否是周末
fun LocalDate.isWeekend(): Boolean {return dayOfWeek.value in listOf(6, 7) // 6=周六, 7=周日
}fun main() {val today = LocalDate.now()val futureDate = today.plusDays(10)println("距离未来日期还有 ${today.daysUntil(futureDate)} 天")println("今天是周末吗? ${today.isWeekend()}")
}

1.3 扩展函数的高级用法
1.3.1 可空接收者扩展

// 为可空String添加扩展函数
fun String?.orEmpty(): String {return this ?: ""
}// 安全解析Int
fun String?.toIntOrZero(): Int {return this?.toIntOrNull() ?: 0
}fun main() {val nullString: String? = nullprintln(nullString.orEmpty().length) // 输出: 0val numString: String? = "42"println(numString.toIntOrZero()) // 输出: 42println(nullString.toIntOrZero()) // 输出: 0
}

1.3.2 泛型扩展函数

// 交换Map中的键值对
fun <K, V> Map<K, V>.invert(): Map<V, K> {return map { Pair(it.value, it.key) }.toMap()
}// 安全转换集合类型
fun <T, R> Collection<T>.convertAll(transform: (T) -> R): List<R> {return mapNotNull { runCatching { transform(it) }.getOrNull() }
}fun main() {val originalMap = mapOf("A" to 1, "B" to 2)println(originalMap.invert()) // 输出: {1=A, 2=B}val strings = listOf("1", "2", "three", "4")val numbers = strings.convertAll { it.toInt() }println(numbers) // 输出: [1, 2, 4]
}

二、扩展属性:为类添加新属性

扩展属性允许我们为现有类添加计算属性:
2.1 基础扩展属性

// 为String添加扩展属性:单词数
val String.wordCount: Intget() = split("\\s+".toRegex()).filter { it.isNotBlank() }.size// 为Int添加扩展属性:是否为偶数
val Int.isEven: Booleanget() = this % 2 == 0fun main() {val text = "Kotlin extensions are powerful"println("单词数: ${text.wordCount}") // 输出: 4println("10是偶数吗? ${10.isEven}") // 输出: trueprintln("7是偶数吗? ${7.isEven}")   // 输出: false
}

三、实战案例:构建DSL风格的验证库

// 验证结果类
data class ValidationResult(val isValid: Boolean,val errors: List<String> = emptyList()
) {operator fun plus(other: ValidationResult): ValidationResult {return ValidationResult(isValid = isValid && other.isValid,errors = errors + other.errors)}
}// 验证器扩展函数
fun String.validate(block: StringValidator.() -> Unit): ValidationResult {val validator = StringValidator(this)validator.block()return validator.result
}// 验证器类
class StringValidator(private val value: String) {private var result = ValidationResult(true)fun notEmpty(message: String = "不能为空") {if (value.isBlank()) {result = ValidationResult(false, result.errors + message)}}fun minLength(length: Int, message: String = "长度不足") {if (value.length < length) {result = ValidationResult(false, result.errors + "$message (最小$length)")}}fun maxLength(length: Int, message: String = "长度超限") {if (value.length > length) {result = ValidationResult(false, result.errors + "$message (最大$length)")}}fun matches(regex: Regex, message: String = "格式不匹配") {if (!value.matches(regex)) {result = ValidationResult(false, result.errors + message)}}
}// 使用示例
fun main() {val password = "secret123"val validation = password.validate {notEmpty()minLength(8)maxLength(20)matches(Regex(".*[0-9].*"), "必须包含数字")matches(Regex(".*[A-Z].*"), "必须包含大写字母") // 这个会失败}if (validation.isValid) {println("密码有效")} else {println("密码无效,原因:")validation.errors.forEach { println("- $it") }}/* 输出:密码无效,原因:- 必须包含大写字母*/
}

四、扩展函数与属性的最佳实践

4.1 设计原则
单一职责:每个扩展函数只做一件事
命名清晰:函数名应准确表达其功能
避免滥用:不是所有工具函数都适合做成扩展
文档完善:为非直观的扩展添加KDoc
4.2 实用技巧
4.2.1 链式调用设计

// 链式构建器风格
class StringBuilder {private val builder = StringBuilder()fun append(text: String): StringBuilder {builder.append(text)return this}fun appendLine(text: String = ""): StringBuilder {builder.appendLine(text)return this}override fun toString(): String = builder.toString()
}// 扩展函数支持链式调用
fun StringBuilder.bold(): StringBuilder {return append("<b>").append(this.toString()).append("</b>")
}fun main() {val result = StringBuilder().append("Hello").appendLine(", Kotlin!").appendLine("This is bold:").bold()println(result)
}

4.2 性能考虑
扩展函数是静态解析的,没有运行时开销
对于频繁调用的扩展,考虑内联(inline)优化
扩展属性有轻微性能开销(每次访问都会调用getter)

// 内联扩展函数示例
inline fun <T> Iterable<T>.sumByLong(selector: (T) -> Long): Long {var sum = 0Lfor (element in this) {sum += selector(element)}return sum
}

五、总结与进阶方向

5.1 核心要点回顾
扩展函数和属性是静态解析的,不会影响原有类的实例
扩展函数可以定义在顶层、类内部或对象中
扩展属性不能有幕后字段(backing field)
可空接收者扩展可以安全处理null值
5.2 扩展函数 vs 成员函数
特性	扩展函数	成员函数
定义位置	类外部	类内部
访问private成员	不能	能
虚函数(可重写)	不能	能
静态分发	是	是
构造函数	不能添加	能

5.3 进阶学习方向
探索Kotlin标准库中的常用扩展(如also, apply, let等)
研究扩展函数在Android开发中的应用(如View绑定)
学习如何为第三方库编写扩展函数
实践用扩展函数构建领域特定语言(DSL)

http://www.lqws.cn/news/599275.html

相关文章:

  • Docker 安装 Neo4j 保姆级教程
  • VuePress 使用并应用 mcommon 模板
  • 3D一览通:在线查看3D模型,让协同更简单
  • GPT-1论文阅读:Improving Language Understanding by Generative Pre-Training
  • opencv入门(4)图像创建和赋值
  • 动手学深度学习13.5. 多尺度目标检测-笔记练习(PyTorch)
  • IDE全家桶专用快捷键----------个人独家分享!!
  • MCP 协议使用核心讲解
  • 数据结构day4——栈
  • 板凳-------Mysql cookbook学习 (十一--------1)
  • 杭州来未来科技 Java 实习面经
  • grom使用mysql快速上手
  • SeaTunnel 社区 2 项目中选“开源之夏 2025”,探索高阶数据集成能力!
  • PHP爬虫实战指南:获取淘宝商品详情
  • 【仿muduo库实现并发服务器】eventloop模块
  • 『深度编码』C++中的参数传递
  • 02.SpringBoot常用Utils工具类详解
  • 【学习方法】框架质疑学习法:破解专业学习的“知识厚度”困境
  • 华为云开始了“开发者空间 AI Agent 开发”活动
  • es的读和写-Reading and writing documents
  • Windows 疑难杂症集 - MsMpEng.exe 磁盘占用率持续高占
  • 发布/订阅模式:解耦系统的强大设计模式
  • 第七讲~~测试工具(禅道项目管理系统)
  • 软件测试期末复习之白盒测试
  • FPGA FMC 接口
  • Electron 进程间通信(IPC)深度优化指南
  • SpringBoot计时一次请求耗时
  • 数据库编程-ORM
  • 基于Pandas和FineBI的昆明职位数据分析与可视化实现(四)- 职位数据可视化(FineBI)
  • Java-String类静态成员方法深度解析