开始掌握一般的闭包和一些常规功能.
给出以下代码:
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方法时会发生什么?
是否to与from从的角度闭合点参数传递?Closure用哪种类型映射它们?
然后在Mailer.sendMailer对象调用mailer.with接收configuration对象的时候在方法内部,对象将它们映射到方法调用.Groovy通过反思来做到这一点?
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)
| 归档时间: |
|
| 查看次数: |
1362 次 |
| 最近记录: |