Глобальные константы в Groovy - PullRequest
45 голосов
/ 01 февраля 2011

Часто желательно объявить константы в верхней части скрипта, на которые можно ссылаться в любом месте скрипта. В Groovy кажется, что если вы объявляете константу с помощью final, она недоступна в дочерних областях. Каково решение для этого самого основного и общего требования? Обходной путь, который я имею сейчас, состоит в том, чтобы создать несвязанную переменную, но это не константа и не элегантный.

Ответы [ 4 ]

77 голосов
/ 01 февраля 2011

Groovy на самом деле не имеет глобальной области видимости.Когда у вас есть отличный сценарий, который не объявляет класс, он неявно застревает в классе с именем сценария.Таким образом, конечные переменные в области видимости верхнего уровня на самом деле являются просто полями неявного класса.Например:

// foo.groovy
final MYCONSTANT = "foobar"
println MYCONSTANT

class Helper {
    def hello() { println MYCONSTANT }  // won't work
}
new Helper().hello()

Более или менее эквивалентно:

class foo {
    def run() {
        final MYCONSTANT = "foobar"
        println MYCONSTANT
        new Helper().hello()
    }
    static main(args) {
        new foo().run()
    }
}

class Helper {
    def hello() { println MYCONSTANT }  // won't work
}

Легко понять, почему это не работает в развернутом виде.Легкий обходной путь - объявить ваши «глобальные переменные» в фиктивном классе, называемом, например, Constants, а затем просто выполнить статический импорт для него.Это даже работает все в одном сценарии.Пример:

import static Constants.*

class Constants {
    static final MYCONSTANT = "foobar"
}

println MYCONSTANT

class Helper {
    def hello() { println MYCONSTANT } // works!
}
new Helper().hello()

РЕДАКТИРОВАТЬ:

Кроме того, сценарии являются частным случаем.Если вы объявляете переменную без def или каких-либо модификаторов, таких как final (то есть просто используете ее), она входит в привязку всего сценария.Таким образом, в этом случае:

CONSTANT = "foobar"
println "foobar"

CONSTANT находится в привязке всего сценария, но в:

final CONSTANT = "foobar"
println "foobar"

CONSTANT является локальной переменной в методе run() сценария.Дополнительную информацию об этом можно найти по адресу https://web -beta.archive.org / web / 20150108090004 / http://groovy.codehaus.org/Scoping+and+the+Semantics+of+%22def%22

21 голосов
/ 08 июля 2015

В Groovy 1.8+ этого можно добиться, используя аннотацию @Field :

import groovy.transform.Field

@Field final String MY_CONSTANT = 'constant'

def printConstant() { println MY_CONSTANT }

printConstant()
0 голосов
/ 23 октября 2018

Лично я бы этого не сделал, но технически вы могли бы сделать

Object.metaclass.MYCONSTANT = 'foobar'

Тогда у каждого объекта есть

0 голосов
/ 12 декабря 2017

Еще один эффективный способ добавления глобальных констант уровня приложения: объявить один интерфейс в подходящей упаковке как

interface applicationConstants {
//All constants goes here.
    static final float PI = 3.14 
    String ADMIN_USER = "ADMIN"
    Map languages = [
        "en":   "English",
        "hi":   "Hindi",
        "mr":   "Marathi"

    ]
// Like above you can declare all application level code constants here.

}

Использование констант в любом классе, как показано ниже,

 import packageNameContainingInterface.applicationConstants // import statement.
 def adminUser = applicationConstants.ADMIN_USER
 println adminUser
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...