关闭和groovy建设者模式

kan*_*eda 2 groovy

开始掌握一般的闭包和一些常规功能.

给出以下代码:

class Mailer {
    void to(final String to) { println "to $to" }
    void from(final String from) { println "from $from" }

    static void send(Closure configuration) {
        Mailer mailer = new Mailer()
        mailer.with configuration
    }  
}

class MailSender {
    static void sendMessage() {
        Mailer.send {
            to 'them'
            from 'me'
        }
    }
}

MailSender.sendMessage()
Run Code Online (Sandbox Code Playgroud)

将闭包传递给Mailer.send方法时会发生什么?

是否tofrom从的角度闭合点参数传递?Closure用哪种类型映射它们?

然后在Mailer.sendMailer对象调用mailer.with接收configuration对象的时候在方法内部,对象将它们映射到方法调用.Groovy通过反思来做到这一点?

Wil*_*ill 5

Groovy可以动态地定义闭包甚至this对象的委托.

with正在设置委托并执行闭包.这是一种实现相同目的的冗长方式:

def math = {
    given 4
    sum 5
    print
}


class PrintMath {
    def initial
    def given(val) {
        initial = val
    }

    def sum(val) {
        initial += val
    }

    def getPrint() {
        println initial
        return initial
    }
}

math.delegate = new PrintMath()
math.resolveStrategy = Closure.DELEGATE_ONLY

assert math() == 9
Run Code Online (Sandbox Code Playgroud)

将闭包传递给Mailer.send方法时会发生什么?

它接收一个尚未执行的代码块.

从Closure的角度来看,to和from是作为参数传递的吗?

不,最好将它们视为java中的匿名类/ lambda,或者是function(){}javascript中的.

Closure用哪种类型映射它们?

无,它们是等待执行的方法调用.但是,它们可以委托给不同的对象.

然后在Mailer对象调用mailer的时候在Mailer.send方法内部接收到配置对象,该对象将它们映射到方法调用.Groovy通过反思来做到这一点?

您可以反编译Groovy类文件以查看正在发生的事情.IIRC,Groovy目前使用"反射器"策略(带arrayOfCallSite缓存)来更快地打电话或者可以使用invokedynamic.

math上面代码中的闭包将导致此类:

// .. a lot of techno-babble

public Object doCall(Object it) {
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    arrayOfCallSite[0].callCurrent(this, Integer.valueOf(4));
    arrayOfCallSite[1].callCurrent(this, Integer.valueOf(5));
    return arrayOfCallSite[2].callGroovyObjectGetProperty(this);
    return null;
}
Run Code Online (Sandbox Code Playgroud)