2008-10-08 7 views

Répondre

230

C'est du sucre syntaxique pour les scripts de base. Omettre la « définition » mot-clé met la variable dans les liaisons pour le script en cours et traite groovy il (la plupart du temps) comme une variable portée globale: mettre

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

En utilisant le mot-clé def ne place pas la variable dans les liaisons de scripts :

def y = 2 

assert y == 2 

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

Prints: « erreur détectée »

en utilisant le mot-clé def dans les grands programmes est importante car elle permet de définir l'étendue dans laquelle la variable se trouve et peut contribuer à préserver l'encapsulation.

Si vous définissez une méthode dans votre script, il ne sera pas avoir accès aux variables créées avec « DEF » dans le corps du script principal car ils ne sont pas dans la portée:

x = 1 
def y = 2 


public bar() { 
    assert x == 1 

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

bar() 

affiche "erreur détectée"

La variable "y" n'est pas incluse dans la portée de la fonction. "x" est dans la portée car groovy vérifiera les liaisons du script courant pour la variable. Comme je l'ai dit plus tôt, il s'agit simplement de sucre syntaxique pour rendre plus rapides les scripts souples (souvent une doublure). La bonne pratique dans les scripts plus volumineux est de toujours utiliser le mot-clé "def" afin de ne pas tomber dans des problèmes de portée étranges ou d'interférer avec des variables que vous n'avez pas l'intention de faire.

+10

bonne réponse approfondie! Merci! – codeLes

5

En fait, je ne pense que ce serait le même comportement ...

variables Groovy nécessitent encore la déclaration, tout simplement pas TYPED déclaration, que le côté droit contient généralement suffisamment d'informations pour Groovy à tapez la variable. Lorsque j'essaie d'utiliser une variable que je n'ai pas déclarée avec def ou un type, j'obtiens une erreur "No such property", car elle suppose que j'utilise un membre de la classe contenant le code.

27

Selon cette page, def est un remplacement pour un nom de type et peut simplement être considéré comme un alias pour Object (ce qui signifie que vous ne se soucient pas du type).

34

Ted's answer est excellent pour les scripts; Ben's answer est standard pour les classes. Comme le dit Ben, pensez-y comme "Objet" - mais il est beaucoup plus cool en ce sens qu'il ne vous contraint pas aux méthodes d'objet. Cela a des implications intéressantes en ce qui concerne les importations.

par exemple.Dans cet extrait, je dois importer 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() 

par exemple. Mais ici, je peux juste « l'aile » aussi longtemps que tout est sur le chemin de classe

// 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() 
+0

pourquoi étiez-vous autorisé à 'nouveau FileInputStream ('Test.groovy'). GetChannel()' sans l'importation? –

+3

@AlexanderSuraphel "tant que tout est sur le chemin des classes" – Hanno

10

En ce qui concerne ce seul script est concerné il n'y a pas de différence pratique. Cependant, les variables définies en utilisant le mot-clé "def" sont traitées comme des variables locales, c'est-à-dire locales à ce seul script. Les variables sans le "def" en face d'eux sont stockées dans une soi-disant liaison lors de la première utilisation. Vous pouvez considérer la liaison comme une zone de stockage générale pour les variables et les fermetures qui doivent être disponibles «entre» les scripts. Donc, si vous avez deux scripts et que vous les exécutez avec le même GroovyShell, le second script sera capable d'obtenir toutes les variables qui ont été définies dans le premier script sans "def".

6

La chose la plus importante est que vous ne voulez vraiment pas créer une variable par accident. C'est un peu OK dans les scripts d'avoir des variables créées sur une affectation, mais dans le code de production, c'est l'un des plus grands maux que vous pouvez rencontrer. Je ne considérerai aucune langue qui permette l'utilisation de cette construction dans le code de production.

J'ai interviewé à plus d'un endroit qui utilisait Visual basic où ils ont posé la question "Quelle est la première ligne dans un fichier VB" et si vous n'avez pas répondu "OPTION EXPLICIT" l'interview s'est arrêtée là. (OPTION EXPLICIT n'autorise pas la création de variables via l'affectation dans VB et force un «dim» explicite)

Voici un exemple de la raison pour laquelle c'est mauvais. Cela fonctionnera (sans défaut assert) si vous copiez le code suivant et collez-le dans un script groovy:

bill = 7 
bi1l = bill + 3 
assert bill == 7 

Il enlève également une partie de la capacité du compilateur pour vous aider refactoring. Par exemple, si vous renommez l'endroit où vous utilisez d'abord la variable, comment le compilateur sait-il vous dire si la seconde utilisation (une affectation) est maintenant une erreur et non une nouvelle variable?

Cette merde est trop dangereuse. Même si cela ne vous a mordu qu'une fois dans votre vie, cela coûterait encore plus de temps que de décliner explicitement les variables des milliers de fois tout au long de votre carrière. Il devient également évident à l'œil juste où il est délayé, vous n'avez pas à deviner.

Dans les scripts c'est plutôt correct car la portée du script est limitée et ils ne sont pas réutilisés et maintenus autant que réécrits, mais un langage qui permet la création en assignation n'est tout simplement pas prêt pour la production.

Questions connexes