Groovy: какова цель “определения” в “определении x = 0”?

В следующей части кода (взятый из Страницы руководства Семантики Groovy), почему префикс присвоение с ключевым словом def?

def x = 0
def y = 5

while ( y-- > 0 ) {
    println "" + x + " " + y
    x++
}

assert x == 5

def ключевое слово может быть удалено, и этот отрывок привел бы к тем же результатам. Таким образом, каков эффект ключевого слова def ?

175
задан lospejos 30 July 2019 в 15:43
поделиться

5 ответов

Это - синтаксический сахар для основных сценариев. Исключение ключевого слова "определения" помещает переменную в привязку для текущего сценария и отличных обработок это (главным образом) как глобально ограниченная по объему переменная:

x = 1
assert x == 1
assert this.binding.getVariable("x") == 1

Используя ключевое слово определения вместо этого не помещает переменную в привязку сценариев:

def y = 2

assert y == 2

try {
    this.binding.getVariable("y") 
} catch (groovy.lang.MissingPropertyException e) {
    println "error caught"
} 

Печать: "ошибка, зафиксированная"

Используя ключевое слово определения в больших программах, важна, поскольку это помогает определить объем, в котором переменная может быть найдена и может помочь сохранить инкапсуляцию.

при определении метода в сценарии это не будет иметь доступа к переменным, которые создаются с "определением" в теле основного сценария, поскольку они не находятся в объеме:

 x = 1
 def y = 2


public bar() {
    assert x == 1

    try {
        assert y == 2
    } catch (groovy.lang.MissingPropertyException e) {
        println "error caught"
    }
}

bar()

печать "ошибка, зафиксированная"

, "y" переменная не находится в объеме в функции. "x" находится в объеме, поскольку отличный проверит привязку текущего сценария для переменной. Как я сказал ранее, это - просто синтаксический сахар для создания быстрых и грязных сценариев более быстрыми для вывода (часто лайнеры).

Хорошая практика в больших сценариях должна всегда использовать ключевое слово "определения", таким образом, Вы не сталкиваетесь со странными проблемами обзора или вмешиваетесь в переменные, Вы не намереваетесь.

270
ответ дан Ted Naleid 23 November 2019 в 20:26
поделиться

ответ Ted's превосходен для сценариев; ответ Ben является стандартным для классов.

, Поскольку Ben говорит, думайте о нем как об "Объекте" - но это намного более прохладно в этом, это не ограничивает Вас к Методам объекта. Это имеет аккуратные последствия относительно импорта.

, например, В этом отрывке я должен импортировать FileChannel

// Groovy imports java.io.* and java.util.* automatically
// but not java.nio.*

import java.nio.channels.*

class Foo {
    public void bar() {
        FileChannel channel = new FileInputStream('Test.groovy').getChannel()
        println channel.toString()
    }
}

new Foo().bar()

, например, Но здесь я могу просто 'крыло это', пока все находится на пути к классу

// Groovy imports java.io.* and java.util.* automatically
// but not java.nio.*
class Foo {
    public void bar() {
        def channel = new FileInputStream('Test.groovy').getChannel()
        println channel.toString()
    }
}

new Foo().bar()
35
ответ дан Community 23 November 2019 в 20:26
поделиться

Согласно этому страница , def является заменой для имени типа и может просто считаться псевдонимом для Object (т.е. показывая, что Вы не заботитесь о типе).

29
ответ дан toniedzwiedz 23 November 2019 в 20:26
поделиться

Насколько этот единственный сценарий обеспокоен, что нет никакого практического различия.

Однако определенное использование переменных ключевого слова "определение" рассматриваются как локальные переменные, то есть, локальный для этого сценария. Переменные без "определения" перед ними хранятся в так называемой привязке после первого использования. Можно думать о привязке как об общей области хранения для переменных и закрытий, которые должны быть доступными "между" сценариями.

Так, если Вы имеете два сценария и выполняете их с тем же GroovyShell, второй сценарий будет в состоянии получить все переменные, которые были установлены в первом сценарии без "определения"

12
ответ дан 23 November 2019 в 20:26
поделиться

На самом деле я не делаю , думают, что это вело бы себя то же...

переменные в Groovy все еще требуют объявления, просто не ВВЕДЕННОЕ объявление, поскольку правая сторона обычно содержит достаточно информации для Groovy для ввода переменной.

, Когда я пытаюсь использовать переменную, которую я не объявил с определением или типом, я получаю ошибку "Никакое такое свойство", так как оно предполагает, что я использую члена класса, содержащего код.

5
ответ дан jjnguy 23 November 2019 в 20:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: