android - 什么是委托(delegate)对象?

标签 android gradle groovy

我目前正在编写 gradle 构建脚本。什么是委托(delegate)对象以及何时使用它们?

class GroovyGreeter {
    String greeting = "Default greeting"
    def printGreeting(){println "Greeting: $greeting"}
}

def myGroovyGreeter = new GroovyGreeter()

myGroovyGreeter.printGreeting()
myGroovyGreeter.greeting = "My custom greeting"
myGroovyGreeter.printGreeting()

/*

The last Groovy feature we'll cover is that closures can have a delegate
object. Any variables or methods referenced in the closure that don't have a
local definition are then evaluated against the closure's delegate. Let's make
a closure that will access the property and method of our GroovyGreeter class.

*/

def greetingClosure = {
    greeting = "Setting the greeting from a closure"
    printGreeting()
}

//greetingClosure() // This doesn't work, because `greeting` isn't defined
greetingClosure.delegate = myGroovyGreeter
greetingClosure() // This works as `greeting` is a property of the delegate

请帮帮我。

最佳答案

什么是闭包的委托(delegate)?

当您将闭包的委托(delegate)设置为另一个对象时,任何无法在闭包范围内解析的属性/方法调用都将由闭包的委托(delegate)解析。在您的示例中,greetingprintGreetinggreetingClosure 闭包范围内未定义

def greetingClosure = {
    greeting = "Setting the greeting from a closure"
    printGreeting()
}

因此,当您将此闭包的委托(delegate)设置为 GroovyGreeter

的实例时
greetingClosure.delegate = myGroovyGreeter

它们被该对象(成功地)解析了,因为它确实定义了具有这些名称的属性和方法。

什么时候使用委托(delegate)?

当您希望 DSL/构建器的用户能够调用具有任何名称的方法时,它们通常用于 DSL 或构建器中,并且方法的名称在 DSL 中几乎像附加方法参数一样使用。以下面的使用构建器生成 XML 的例子

def writer = new StringWriter()
def xml = new MarkupBuilder(writer) 

xml.records() { 
    car(name:'HSV Maloo', make:'Holden', year:2006) {
        country('Australia')
        record(type:'speed', 'Production Pickup Truck with speed of 271kph')
    }
}

def records = new XmlSlurper().parseText(writer.toString())

创建构建器后我们做的第一件事是调用 records 并传递一个闭包参数。实际上,在 MarkupBuilder 中的任何地方都没有定义一个带有闭包参数的 records 方法,但是所有未定义的方法都将被路由到 MarkupBuilder,使用 Groovy's methodMissing feature .

在传递给 records 的闭包中,我们调用了各种其他未在编译时定义的方法,例如汽车MarkupBuilder 如何解析这些方法调用?因为这个闭包的委托(delegate)被设置为 MarkupBuilder 实例。

关于android - 什么是委托(delegate)对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39067767/

相关文章:

java - Jooq 与 gradle 使用 nu.studer 插件::如何在 build.gradle 中定义匹配器策略

android - Android Studio Gradle在Android L上设置了目标API

scope - 如何在 Gradle 构建中使用为 jar 文件提供的范围?

grails - 完全禁用javamelody grails插件

android - SeekBar 缩略图动画

android - 如何为糖 ORM 查询做日期条件

java - 从相机 Intent 拍摄照片并在其上覆盖另一个小图像

Android Honeycomb 和 imeOptions

unit-testing - gmaven 没有找到测试

grails - 如何在我的 Java 项目中使用 groovy 域类?