2010-09-17 4 views
2

J'ai obtenu le code suivant se référant par exemple au chapitre 6 de « Programmation Scala »:Pourquoi le résultat est-il différent pour un minuscule changement concernant l'initialisation de val de membre de trait abstrait?

object HelloWorld { 
    def main(args: Array[String]) { 
    trait AbstractT2 { 
     println("In AbstractT2:") 
     val value: Int 
     val inverse = 1.0/value // ??? 
     println("AbstractT2: value = " + value + ", inverse = " + inverse) 
    } 

    val c2b = new AbstractT2 { 
     println("In c2b:") //---->line 1 
     val value = 10  //---->line 2 
    } 
    println("c2b.value = " + c2b.value + ", inverse = " + c2b.inverse) 
    } 
} 

Le résultat du code ci-dessus est:

In AbstractT2: 
AbstractT2: value = 0, inverse = Infinity 
In c2b: 
c2b.value = 10, inverse = Infinity 

Depuis l'initialisation de la classe anonyme est après la l'initialisation des caractères, le résultat est compréhensible. Mais si j'échange ligne 1 et la ligne 2 dans l'exemple ci-dessus, de sorte que val value = 10 précède println("In c2b:"), le résultat sera:

In AbstractT2: 
AbstractT2: value = 10, inverse = 0.1 
In c2b: 
c2b.value = 10, inverse = 0.1 

Il semble que cette fois l'initialisation est réussie mais il est faux du point de vue linguistique. Je ne peux pas comprendre pourquoi. Quelqu'un peut-il aider à ce sujet? Merci beaucoup.

+0

Hmmm .... Scala contre 2.8.0.final vérifiée, et voir les mêmes résultats dans les deux cas: En AbstractT2: AbstractT2: valeur = 0, inverse = infini dans C2B: c2b.value = 10, inverse = Infini –

+0

Je peux confirmer le commentaire de Vasil. Idem ici avec Scala 2.8.0.final. Quelle version utilise-tu? –

+0

La version que j'ai utilisée pour obtenir le résultat ci-dessus est 2.7.7.final. J'ai testé cela contre 2.8.0 tout à l'heure, et les résultats pour les deux cas sont corrects comme vous l'avez dit. Donc, il semble être un bug de 2.7.7 ou 2.7.x? – Hongfei

Répondre

3

Jusqu'à 2.7 Scala déplacé valeur initialisations devant le constructeur superclasse jusqu'à ce qu'une initialisation qui fait référence this a été rencontrée. Là, ça s'arrêterait. Beaucoup, beaucoup plus tôt, ce comportement était nécessaire pour faire fonctionner certains modèles de composition. Plus tard, nous avons introduit les premières définitions pour que les mêmes modèles fonctionnent de manière plus robuste. Mais puisque le comportement était difficile à changer, il nous a fallu jusqu'à 2,8 pour le faire.

5

La sémantique d'initialisation est passée de 2,7 à 2,8. Voici l'engagement, en 2008. "HARD HATS ON!"

https://lampsvn.epfl.ch/trac/scala/changeset/16745

+0

Salut, voulez-vous dire que le comportement actuel de 2.7 est également correct comme prévu? Merci. – Hongfei

+0

Je veux dire que le comportement que vous démontrez est le comportement attendu en 2.7. "Corriger" est une affirmation plus ambitieuse avec laquelle je ne peux ni confirmer ni infirmer, mais le point est discutable à moins que vous ne vouliez commencer à maintenir la branche 2.7. – extempore

Questions connexes