Определенное вами замыкание ничего не сохраняет в объекте binding
- оно просто возвращает строку, переданную как переменную str
, повторяется 4 раза.
Этот объект binding
хранит все переменные, которые были определеныбез указания их типов или использования ключевого слова def
.Это делается с помощью функции метапрограммирования Groovy (точнее, getProperty
и setProperty
).Поэтому, когда вы определяете переменную s
, например:
def clsr = {
s = str*4
return s
}
, тогда это закрытие создаст привязку с ключом s
и значением, вычисленным из выражения str * 4
.Этот объект привязки является ничем иным, как картой, доступ к которой осуществляется с помощью методов getProperty
и setProperty
.Поэтому, когда Groovy выполняет s = str * 4
, он вызывает setProperty('s', str * 4)
, поскольку переменная / свойство s
не определена.Если мы сделаем немного простое изменение, например:
def clsr = {
def s = str*4 // or String s = str * 4
return s
}
, то привязка s
не будет создана, потому что метод setProperty
не выполняется.
Еще один комментарий к вашему примеру,Если вы хотите увидеть что-либо в объекте привязки, вам нужно вызвать возвращаемое закрытие.В приведенном выше примере возвращаемое замыкание возвращается, но оно никогда не вызывается.Если вы сделаете:
def c = fourtify("aa")
c.call()
println("binding variables: ${c.getBinding().getVariables()}")
, тогда будет вызвано ваше замыкание, и объект привязки будет содержать привязки (если они есть).Теперь, если вы измените свой пример на что-то вроде этого:
def fourtify(String str) {
def clsr = {
def n = 4 // it does not get stored as binding
s = str * n
return s
}
return clsr
}
def c = fourtify("aa")
c.call()
println("binding variables: ${c.getBinding().getVariables()}")
, вы увидите следующие выходные данные:
binding variables: [args:[], s:aaaaaaaa]
Надеюсь, это поможет.