2010-04-29 10 views
3

En utilisant XScalaWT, ce Scala 2.7 compilé sous:Scala 2.8: _ comportement changé?

class NodeView(parent: Composite) extends Composite(parent) { 
    var nodeName: Label = null 

    this.contains(
    label(
     nodeName = _ 
    ) 
) 
} 

Avec 2.8.0 RC1, je reçois cette erreur:

type mismatch; found : main.scala.NodeView required: org.eclipse.swt.widgets.Label

Les types sont:

label(setups: (Label => Unit)*)(parent: Composite) : Label 
contains(setups: (W => Unit)*) : W 

Il semble donc comme _ se lie maintenant à la fonction externe au lieu de l'interne.

Est-ce que ce changement est intentionnel?

MISE À JOUR: Voici un exemple réduit:

Scala 2.7.7:

scala> var i = 0 
i: Int = 0 

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)  
conv: ((Int) => Unit)(Boolean) => Unit 

scala> def foo(g: Boolean => Unit) { g(true) }  
foo: ((Boolean) => Unit)Unit 

scala> foo(conv(i = _))  

scala> i  
res4: Int = 1 

Scala 2.8.0RC3:

scala> var i = 0 
i: Int = 0 

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0) 
conv: (f: (Int) => Unit)(Boolean) => Unit 

scala> def foo(g: Boolean => Unit) { g(true) } 
foo: (g: (Boolean) => Unit)Unit 

scala> foo(conv(i = _)) 
<console>:9: error: type mismatch; 
found : Boolean 
required: Int 
     foo(conv(i = _)) 
       ^

scala> foo(conv(j => i = j)) 

scala> i 
res3: Int = 1 

Il est intéressant, cela fonctionne:

scala> foo(conv(println _)) 
1 
+0

Pouvez-vous poster plus ou le message d'erreur? –

+0

J'ai posté le message d'erreur: "incompatibilité de type; found: main.scala.NodeView requis: org.eclipse.swt.widgets.Label" –

+0

À quelle ligne le compilateur fait-il référence? –

Répondre

2

Voici la réponse que je suis arrivé de Lukas Rytz sur la liste scala-utilisateur:

Hi Alexey,

there has been a change in semantics when we introduced named arguments. An expression

foo(a = _) 

used to be parsed as follows:

foo(x => a = x) 

In 2.8, "a" is treated as a named argument, i.e. the expression is parsed as:

x => foo(a = x) 

I will add a migration warning for this change.

+1

Dans certains cas, vous pouvez obtenir l'ancien comportement avec des accolades à la place. – Debilski

0

j'ai remarqué la même chose et demandé sur le blog de Dave:

http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:simplifying_swt_with_scala#comment__930ba2f0a020203873d33decce01ebc2

Pas de réponse encore là cependant. Tout comme vous le dites, il semble que le _ se lie à la fermeture extérieure plutôt qu'à la fermeture intérieure.

Changer

nodeName = _ 

à

x => nodeName = x 

résout le problème.

+0

Oui, mais cela nuit à la lisibilité du code XScalaWT. –

+0

Oui, bien sûr, et c'est vraiment bizarre que la sémantique de _ ait changé de façon drastique. J'aimerais vraiment comprendre ce qui s'est passé aussi. –

+0

Si vous n'avez pas encore vu la réponse, ce n'est pas la sémantique de _ qui a changé, mais celle de =. –