4

我对 Groovy 很陌生。我想知道如何在 Groovy 中实现闭包。

让我们说:

def a = { println "Hello" }
a()

什么时候a()完成,幕后实际发生了什么?调用哪个方法a()使闭包可执行?

提前致谢。

4

2 回答 2

6

基本上:

  • 您的闭包是具有特定名称的类
  • a()调用doCall()哪个调用doCall(Object it)(隐含it在闭包中)
  • acallsite包含方法名称 (2 x println) - 并使用适当的参数调用

干得好:

对于这个 Groovy 脚本:

def a = { println "Hello"; println "Hello2" }
a()

闭包a看起来像这样:

class Test$_run_closure1 extends Closure
implements GeneratedClosure
{

    public Object doCall(Object it)
    {
        CallSite acallsite[] = $getCallSiteArray();
        acallsite[0].callCurrent(this, "Hello");
        return acallsite[1].callCurrent(this, "Hello2");
    }

    public Object doCall()
    {
        CallSite acallsite[] = $getCallSiteArray();
        return doCall(null);
    }

    protected MetaClass $getStaticMetaClass()
    {
        if(getClass() != Test$_run_closure1)
            return ScriptBytecodeAdapter.initMetaClass(this);
        ClassInfo classinfo = $staticClassInfo;
        if(classinfo == null)
            $staticClassInfo = classinfo = ClassInfo.getClassInfo(getClass());
        return classinfo.getMetaClass();
    }

    public static void __$swapInit()
    {
        CallSite acallsite[] = $getCallSiteArray();
        $callSiteArray = null;
    }

    private static void $createCallSiteArray_1(String as[])
    {
        as[0] = "println";
        as[1] = "println";
    }

    private static CallSiteArray $createCallSiteArray()
    {
        String as[] = new String[2];
        $createCallSiteArray_1(as);
        return new CallSiteArray(Test$_run_closure1, as);
    }

    private static CallSite[] $getCallSiteArray()
    {
        CallSiteArray callsitearray;
        if($callSiteArray == null || (callsitearray = (CallSiteArray)$callSiteArray.get()) == null)
        {
            callsitearray = $createCallSiteArray();
            $callSiteArray = new SoftReference(callsitearray);
        }
        return callsitearray.array;
    }

    static Class _mthclass$(String s)
    {
        try
        {
            return Class.forName(s);
        }
        catch(ClassNotFoundException classnotfoundexception)
        {
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());
        }
    }

    private static ClassInfo $staticClassInfo;
    public static transient boolean __$stMC;
    private static SoftReference $callSiteArray;

    static 
    {
        __$swapInit();
    }

    public Test$_run_closure1(Object _outerInstance, Object _thisObject)
    {
        CallSite acallsite[] = $getCallSiteArray();
        super(_outerInstance, _thisObject);
    }
}
于 2012-08-03T14:26:53.677 回答
4

它最终调用了其中一种Closure.call方法(在本例中为没有 args的方法)

文档中有关于此的更多信息

于 2012-08-03T13:25:43.140 回答