Я использую Groovy v3.0.1.
Я вижу ответ, которого я не ожидал от следующего кода. Я строю карту глагола, существительного и замыканий.
Первый раз, когда я использую methodReference mybed::trySleep
в качестве передаваемого замыкания, но устанавливаю делегат в качестве объекта данных и использую разрешение DELEGATE_ONLY.
Вторая запись передает прямое замыкание в строке как замыкание.
package playpen
class Bed {
String name
String bedSize = "5ft by 6ft"
static sTrySleep () {
println "called static on sleep"
}
void trySleep (arg = null) {
println "called instance.onSleep() for name (${->name}) with " + arg ?: "<no arg>"
}
}
Bed mybed = new Bed(name:"wills bed")
class DataObject {
String name = "first data object"
int height = 10
int length = 12
int width = 5
}
Map verbNounLookup = new HashMap()
Map buildAction (Map vnl, String verb, String noun, data, Closure method) {
method.delegate = data
method.resolveStrategy = Closure.DELEGATE_ONLY
def lookup = [(verb): [(noun): method]]
vnl.putAll(lookup)
lookup
}
buildAction (verbNounLookup, "go", "snooze", new DataObject(), mybed::trySleep)
buildAction (verbNounLookup, "do", "thing", new DataObject(), {println "called with $it, and sees name as: $name"})
def action = verbNounLookup.go.'snooze'
action ("hi")
action = verbNounLookup.do.thing
action( "william")
Я представлял для первого поиска, что в качестве ссылки на метод динамически строит свою строку GString с помощью {-> name}, но делегат метода был переопределен для моего объекта данных, поэтому вызов этого метода разрешит имя объекта данных в качестве нового делегата.
Вторая запись, являющаяся моим внутренним закрытием, разрешает имя объекта данных делегата как вы ожидаете.
Это не так - вместо этого он разрешает имя в экземпляре myBed. Это правильное поведение?
Вывод:
called instance.onSleep() for name (wills bed) with hi
called with william, and sees name as: first data object