下面是我在gradle文档中遇到的代码段https://docs.gradle.org/current/userguide/tutorial_using_tasks.html
val hello by tasks.registering {
doLast {
println("Hello Earth")
}
}
hello {
doFirst {
println("Hello Venus")
}
}
在上面,hello是提供任务定义/操作的TaskProvider类型。向hello的第二个调用是扩展任务的行为。
此delegate使用对我来说似乎有些混乱。以下是困扰我的问题:
1)在检查反编译的字节码时,我看到tasks.registering返回RegisteringDomainObjectDelegateProviderWithAction对象,该对象应用作委托,因此应为代表工作,但如我所见,未提供方法。相反,类RegisteringDomainObjectDelegateProviderWithAction具有类型为[[tasks的delegateProvider属性,该属性应该提供delegate。有人可以帮助我了解一下,代表团在这里如何工作吗?
2)第二个调用应该为hello
任务添加行为。由于hello是一个属性,我们如何将lambda /行为传递给它?我想念什么?我已经看过kotlin文档,该文档对委托提供了很好的解释,但无助于理解上述情况https://kotlinlang.org/docs/reference/delegated-properties.html
由于我是Kotlin的新手,请提供详细的说明。该委托通过在provideDelegate
上定义的扩展运算符方法RegisteringDomainObjectDelegateProviderWithAction
进行工作:
operator fun RegisteringDomainObjectDelegateProviderWithAction<out TaskContainer, Task>.provideDelegate(
receiver: Any?,
property: KProperty<*>
) = ExistingDomainObjectDelegate.of(
delegateProvider.register(property.name, action)
)
provideDelegate
运算符允许在委托创建中使用更复杂的逻辑。按照docs:
通过定义
provideDelegate
运算符,您可以扩展创建将属性实现委派到的对象的逻辑。如果by右侧使用的对象将provideDelegate
定义为成员或扩展函数,则将调用该函数以创建属性委托实例。
- 关于“将lambda传递给属性”:
这通过重载
invoke
operator作为invoke
类的扩展功能来实现:TaskProvider
基本上,呼叫
operator fun <T> NamedDomainObjectProvider<T>.invoke(action: T.() -> Unit) = configure(action)
被减为hello { /* your lambda */ }
。