首页 文章

关闭和groovy建设者模式

提问于
浏览
2

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

给出以下代码:

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()

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

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

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

1 回答

  • 5

    Groovy可以动态define the delegate的一个闭包甚至 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
    

    当你将一个闭包传递给Mailer.send方法时,会发生什么?

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

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

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

    Closure将它们映射到哪些类型?

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

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

    你可以decompile a Groovy class file看看发生了什么 . IIRC,Groovy目前使用"reflector"策略(使用 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;
    }
    

相关问题