这篇涉及到的知识点:
扩展函数:Kotlin 扩展函数详解_kotlin扩展函数-CSDN博客
设计模式: builder 模式 :建造者模式(Builder)-CSDN博客
高阶函数 :Kotlin --- 函数,高阶函数_kotlin 高阶函数-CSDN博客
高阶函数,父子组件: Compose 父子组件的通信_jetpack compose 子组件数据传递-CSDN博客
详细解释这个 configure 方法的语法和工作原理:
configure 方法解析
语法分解
fun configure(init: EventConfig.() -> Unit): EventHandlerManager {
eventConfig = EventConfig().apply(init)
return this
}
各部分含义
init: EventConfig.() -> Unit
- init 是参数名
- EventConfig.() 是带接收者的函数类型
- -> Unit 表示函数返回 Unit(无返回值)
EventConfig.() 是什么?
- 这是 Kotlin 的扩展函数语法
- 表示这个函数在 EventConfig 对象内部执行
- 函数内部可以直接访问 EventConfig 的属性和方法
EventConfig().apply(init)
- EventConfig() 创建新对象
- .apply(init) 在新对象上执行 init 函数
apply { } 和apply() 区别?
真正的区别是:
- apply { } 是直接写代码块
- apply(init) 是通过函数参数传入代码块
但执行时机是相同的,都是立即执行。
实际使用示例
调用方式
// 调用方式
eventHandlerManager.configure {
// 这里的 this 就是 EventConfig 对象
addValidator { rect -> rect != null }
addHandler(EventType.CHAT) { rect ->
handleChat(rect)
}
}
执行过程
// 1. 创建新的 EventConfig 对象
val newConfig = EventConfig()
// 2. 在 newConfig 上执行配置函数
newConfig.apply {
addValidator { rect -> rect != null }
addHandler(EventType.CHAT) { rect ->
handleChat(rect)
}
}
// 3. 将配置好的对象赋值给 eventConfig
eventConfig = newConfig
游戏类比
就像角色创建界面:
// 创建角色
val character = Character()
// 配置角色属性
character.apply {
name = "战士"
level = 10
weapon = "剑"
armor = "铁甲"
}
// 使用配置好的角色
player.character = character
等价的传统写法
传统方式
// 传统方式
fun configureTraditional(): EventHandlerManager {
val config = EventConfig()
config.addValidator { rect -> rect != null }
config.addHandler(EventType.CHAT) { rect ->
handleChat(rect)
}
eventConfig = config
return this
}
扩展函数方式
// 使用扩展函数的方式(当前实现)
fun configure(init: EventConfig.() -> Unit): EventHandlerManager {
eventConfig = EventConfig().apply(init)
return this
}
调用对比
// 传统方式调用
eventHandlerManager.configureTraditional()
// 扩展函数方式调用(更优雅)
eventHandlerManager.configure {
addValidator { rect -> rect != null }
addHandler(EventType.CHAT) { rect ->
handleChat(rect)
}
}
为什么这样设计?
- 链式调用:return this 支持链式调用
- 代码块:{} 提供配置代码块
- 作用域:在 EventConfig 作用域内执行
- 简洁性:比传统方式更简洁
完整示例
// 配置事件处理器
eventHandlerManager
.configure {
// 添加验证器
addValidator { rect -> rect != null }
addValidator { rect -> rect.text.isNotEmpty() }
// 添加事件处理器
addHandler(EventType.CHAT) { rect ->
Log.d("Chat", "处理聊天事件: ${rect.text}")
}
addHandler(EventType.PDF) { rect ->
Log.d("PDF", "处理PDF事件: ${rect.text}")
}
}
.registerAllHandlers() // 链式调用
/**
* 注册所有事件处理器
* 根据配置注册相应的事件处理器
*/
fun registerAllHandlers() {
eventConfig.handlers.forEach { (type, handler) ->
registerHandler(type, handler)
}
Log.d(TAG, "所有事件处理器注册完成")
}
/**
* 注册单个事件处理器
* @param type 事件类型
* @param handler 处理函数
*/
private fun registerHandler(type: EventType, handler: (ColoredRect) -> Unit) {
when (type) {
EventType.CHAT -> deepLearnView.registerButtonClickHandler(RectType.START_CHAT) { rect ->
if (validateRect(rect)) {
handler(rect)
}
}
EventType.QUESTION -> deepLearnView.registerQuestionConfirmButtonClickHandler { rect ->
if (validateRect(rect)) {
handler(rect)
}
}
EventType.QUESTION_BUTTON -> deepLearnView.registerQuestionButtonClickHandler(0) { rect, buttonIndex, buttonText ->
if (validateRect(rect)) {
// 这里需要特殊处理,因为问答按钮处理器有额外参数
// 可以扩展 EventConfig 来支持带参数的处理函数
handler(rect)
}
}
EventType.OCR -> deepLearnView.registerOcrButtonClickHandler { rect ->
if (validateRect(rect)) {
handler(rect)
}
}
EventType.OCR_ADD_IMAGE -> deepLearnView.registerOcrAddImageClickHandler { rect ->
if (validateRect(rect)) {
handler(rect)
}
}
EventType.PDF -> deepLearnView.registerButtonClickHandler(RectType.PDF) { rect ->
if (validateRect(rect)) {
handler(rect)
}
}
EventType.SEARCH -> deepLearnView.registerButtonClickHandler(RectType.SEARCH) { rect ->
if (validateRect(rect)) {
handler(rect)
}
}
}
}
这样设计让配置代码更加优雅和直观,就像在配置一个对象一样!