wake-up-neo.net

Globale Konstanten in Groovy

Es ist oft erwünscht, Konstanten oben in einem Skript zu deklarieren, auf die an anderer Stelle im Skript verwiesen werden kann. In Groovy scheint es, wenn Sie eine Konstante mit final deklarieren, ist sie in untergeordneten Bereichen nicht zugänglich. Was ist die Lösung für diese sehr grundlegende und gemeinsame Anforderung? Die Problemumgehung, die ich jetzt habe, besteht darin, eine ungebundene Variable zu erstellen, aber dies ist keine Konstante und nicht elegant.

44
justGroovy

Groovy hat eigentlich keinen globalen Geltungsbereich. Wenn Sie ein grooviges Skript haben, das keine Klasse deklariert, bleibt es implizit in einer Klasse mit dem Namen des Skripts hängen. Endvariablen im Bereich der obersten Ebene sind also eigentlich nur Felder der impliziten Klasse. Zum Beispiel:

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

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

Ist mehr oder weniger gleichbedeutend mit:

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
}

Es ist leicht zu erkennen, warum es nicht so funktioniert. Eine einfache Lösung ist die Deklaration Ihrer "Globals" in einer Dummy-Klasse, die z. Konstanten und führen Sie einfach einen statischen Import aus. Es funktioniert sogar alles in einem einzigen Skript. Beispiel:

import static Constants.*

class Constants {
    static final MYCONSTANT = "foobar"
}

println MYCONSTANT

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

BEARBEITEN: 

Skripte sind auch ein Sonderfall. Wenn Sie eine Variable ohne def oder ohne Modifizierer wie final deklarieren (d. H. Verwenden Sie sie einfach), wird sie in eine scriptweite Bindung übernommen. Also in diesem Fall:

CONSTANT = "foobar"
println "foobar"

CONSTANT ist in der scriptweiten Bindung, aber in:

final CONSTANT = "foobar"
println "foobar"

CONSTANT ist eine lokale Variable in der run()-Methode des Skripts. Weitere Informationen hierzu finden Sie unter https://web-beta.archive.org/web/20150108090004/http://groovy.codehaus.org/Scoping+and+the+Semantics+of+%22def%22

75
ataylor

In Groovy 1.8+ können Sie dies mit der Annotation @Field erreichen:

import groovy.transform.Field

@Field final String MY_CONSTANT = 'constant'

def printConstant() { println MY_CONSTANT }

printConstant()
20
bmaupin

Ich persönlich würde das nicht tun, aber technisch könnten Sie es tun

Object.metaclass.MYCONSTANT = 'foobar'

Dann hat jedes Objekt es

0
Adam Taylor

Die andere effiziente Möglichkeit, die Konstanten der globalen Anwendungsebene hinzuzufügen, ist Deklarieren Sie ein interface in einem geeigneten Paket als 

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.

}

Verwendung von Konstanten in jeder Klasse wie folgt,

 import packageNameContainingInterface.applicationConstants // import statement.
 def adminUser = applicationConstants.ADMIN_USER
 println adminUser
0
Nitin Dhomse