2016-11-10 3 views
3

Сейчас я изучаю Groovy, и я столкнулся с чем-то, чего не понимаю, и надеюсь, что вы сможете пролить свет.Groovy: В чем разница между определением переменной без «def» и с использованием привязки?

В отношении следующего примера:

import groovy.transform.Field 
    @Field List awe = [1, 2, 3] 
    def awesum() { awe.sum() } 
    assert awesum() == 6 

Я понимаю, что это анкеровка позволяет мне изменить сферу благоговения переменного от запускаемого на уровне методы сценария на уровень класса сценария ,

Но тогда я думаю о разнице между, определяющей переменных с Защитой или без, например:

def var = "foo" 

и

var = "foo" 

Насколько я понимаю, разница между этими двумя примерами является разница в объеме. Когда я присваиваю значение переменной без «def» или другого типа, в скрипте Groovy он добавляется к «привязке», глобальным переменным для скрипта. Это означает, что к нему можно получить доступ ко всем функциям скрипта.

Итак, принимая во внимание как «@Field» и определить переменную без использования «DEF» и после этой линии мысли я изменил пример кода для этого:

import groovy.transform.Field 
    awe = [1, 2, 3] 
    def awesum() { awe.sum() } 
    assert awesum() == 6 

И это работает.

Так что мой вопрос в том, почему использовать привязку? если вы можете достичь той же цели, задав переменную без «def»?

ответ

3

Вы не достигают той же цели - увидеть разницу ниже

import groovy.transform.Field 
awe = [1, 2, 3] 
def awesum() { awe.sum() } 
assert awesum() == 6 
awe = 1 

прекрасно работают как переменная динамически типизированных. Наоборот это не удается

import groovy.transform.Field 
@Field List awe = [1, 2, 3] 
def awesum() { awe.sum() } 
assert awesum() == 6 
awe = 1 

Поскольку переменная является сильным типизированных (java.util.ArrayList)

Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '1' with class 'java.lang.Integer' to class 'java.util.List' 
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '1' with class 'java.lang.Integer' to class 'java.util.List' 
     at FieldTest1.run(FieldTest1.groovy:5) 
3

@Field моложе скриптов и предполагаемое использование, чтобы дать открытые блоки способность к имеют дополнительное состояние. Если вы довольны привязкой, на самом деле нет большой причины для этого. Если вам нужны значения в привязке, то @Field не является альтернативой. С другой стороны, если связывание должно содержать только определенные переменные, то @Field может стать обязательным

Пример для предполагаемого использования:

def cl = { 
    Field x = 1 
    x++ 
} 

В этом примере блок открытые сл бы поля х, сценарий не будет иметь x в привязке и не будет локальной переменной x. Но присваивание x = 1 выполняется только один раз, когда создается открытый блок. Но вы все равно можете изменить значение по операциям в этом поле. Таким образом, каждый вызов cl() будет генерировать новое значение, начиная с 1.

Смежные вопросы