下面是我在 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 对象,该对象应该用作委托(delegate),因此应该提供 getValue() 和委托(delegate)的 setValue() 方法可以正常工作,但正如我所见,没有提供方法。相反,RegisteringDomainObjectDelegateProviderWithAction 类具有 tasks 类型的 delegateProvider 属性,该属性应该提供委托(delegate)。任何人都可以帮助我理解委托(delegate)是如何工作的吗?
2) 第二次调用应该向 hello 任务添加行为。由于 hello 是一个属性,我们如何向它传递 lambda/行为?我错过了什么?
我已经看过 kotlin 文档,它对委托(delegate)提供了很好的解释,但无助于理解上述情况 https://kotlinlang.org/docs/reference/delegated-properties.html
由于我是 Kotlin 新手,因此希望能得到详细的解释。
最佳答案
关于委托(delegate)的使用:
委托(delegate)通过扩展运算符方法进行工作
provideDelegate
定义于RegisteringDomainObjectDelegateProviderWithAction
:operator fun RegisteringDomainObjectDelegateProviderWithAction<out TaskContainer, Task>.provideDelegate( receiver: Any?, property: KProperty<*> ) = ExistingDomainObjectDelegate.of( delegateProvider.register(property.name, action) )
provideDelegate
运算符允许在委托(delegate)创建中使用更复杂的逻辑。根据docs :By defining the
provideDelegate
operator you can extend the logic of creating the object to which the property implementation is delegated. If the object used on the right hand side of by definesprovideDelegate
as a member or extension function, that function will be called to create the property delegate instance.关于“将 lambda 传递给属性”:
这是通过重载
invoke
operator 来实现的作为TaskProvider
上的扩展函数类:operator fun <T> NamedDomainObjectProvider<T>.invoke(action: T.() -> Unit) = configure(action)
基本上,调用
hello { /* your lambda */ }
脱糖为hello.invoke { /* your lambda */ }
.
关于kotlin - Gradle 的 Kotlin DSL 中令人困惑的属性委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61263667/