简体   繁体   English

groovy闭包参数

[英]groovy closure parameters

The following example of using the sendMail method provided by the grails mail plugin appears in this book . 以下使用grails邮件插件提供的sendMail方法的示例出现在本书中

sendMail {
    to "foo@example.org"
    subject "Registration Complete"
    body view:"/foo/bar", model:[user:new User()]
}

I understand that the code within {} is a closure that is passed to sendMail as a parameter. 我理解{}中的代码是一个闭包,它作为参数传递给sendMail。 I also understand that to , subject and body are method calls. 我也明白tosubjectbody的方法调用。

I'm trying to figure out what the code that implements the sendMail method would look like, and my best guess is something like this: 我试图找出实现sendMail方法的代码是什么样的,我最好的猜测是这样的:

MailService {

    String subject
    String recipient
    String view
    def model

    sendMail(closure) {
        closure.call()
        // Code to send the mail now that all the 
        // various properties have been set
    }

    to(recipient) {
        this.recipient = recipient
    }

    subject(subject) {
        this.subject = subject;
    }

    body(view, model) {
        this.view = view
        this.model = model
    }
}

Is this reasonable, or am I missing something? 这是合理的,还是我错过了什么? In particular, are the methods invokedwithin the closure ( to , subject , body ), necessarily members of the same class as sendMail ? 特别是,在闭包( tosubjectbody )中调用的方法是否必须与sendMail属于同一类的sendMail

Thanks, Don 谢谢,唐

MailService.sendMail closure delegating: MailService.sendMail关闭委托:

 MailMessage sendMail(Closure callable) {
    def messageBuilder = new MailMessageBuilder(this, mailSender)
    callable.delegate = messageBuilder
    callable.resolveStrategy = Closure.DELEGATE_FIRST
    callable.call()

    def message = messageBuilder.createMessage()
    initMessage(message)
    sendMail message
    return message
}

and for example, the method to at MailMessageBuilder: 例如,MailMessageBuilder的方法:

void to(recip) {
    if(recip) {
        if (ConfigurationHolder.config.grails.mail.overrideAddress)
            recip = ConfigurationHolder.config.grails.mail.overrideAddress
        getMessage().setTo([recip.toString()] as String[])
    }
}

I'm not sure exactly what the sendMail method does as I do not have the book you mention. 我不确定sendMail方法究竟是什么,因为我没有你提到的那本书。 The sendMail method does indeed take a closure as you describe but it probably uses a builder rather than being executed in the normal way. sendMail方法确实在您描述时采用了闭包,但它可能使用构建器而不是以正常方式执行。 Essentially that would be a Domain Specific Language for describing an email to be sent. 基本上,这将是用于描述要发送的电子邮件的域特定语言。

The reason the class you defined would not work is that the scope of the closure is where it is declared not where it is run. 您定义的类不起作用的原因是闭包的范围是声明它不在其运行的位置。 So having your closure call the to() method, it would not be able to call the to method in MailService unless you passed the instance of mail service into the closure. 因此,让闭包调用to()方法,除非将邮件服务实例传递给闭包,否则它将无法在MailService中调用to方法。

With a few modifications, your example could work though using a regular closure. 通过一些修改,您的示例可以使用常规闭包。 The following changes to the call and 呼叫的以下更改和

// The it-> can be omitted but I put it in here so you can see the parameter
service.sendMail {it->
    it.to "foo@example.org"
    it.subject "Registration Complete"
    it.body view:"/foo/bar", model:[user:new User()]
}

The sendMail method in the class should look like this 类中的sendMail方法应该如下所示

def sendMail(closure) {
    closure(this)
    // Code to send the mail now that all the 
    // various properties have been set
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM