2009-06-24 7 views
2
object Test extends Application { 

    // compiles: 
    Map[Int, Value](
    0 -> KnownType(classOf[Object]), 
    1 -> UnknownValue()) 

    // does not compile: 
    Map(
    0 -> KnownType(classOf[Object]), 
    1 -> UnknownValue()) 
} 
sealed trait Value { 
    def getType: Option[Class[_]] 
} 
case class UnknownValue() extends Value { 
    def getType = None 
    // compiles if changed to: 
    // def getType: Option[Class[_]] = None 
} 
case class KnownType(typ: Class[_]) extends Value { 
    def getType = Some(typ) 
} 

Le code ci-dessus ne peut pas être compilé. Le message d'erreur du compilateur est:Pourquoi le code Scala suivant ne compile pas, sauf si des paramètres de type explicites sont ajoutés?

 
Experiment.scala:10: error: type mismatch; 
found : (Int, KnownType) 
required: (Int, Product with Value{def getType: Option[java.lang.Class[_$2]]}) where type _$2 
    0 -> KnownType(classOf[Object]), 
    ^
one error found 

Si je change la déclaration de méthode de UnknownValue être def getType: Option[Class[_]] = None puis aussi la carte() sans paramètres de type compile.

Pourquoi?

Répondre

1

J'ai posté la question à la liste de diffusion scala-utilisateur et aussi ils ont dit que c'est un bug.

2

Hmm, c'est bizarre. On dirait un bug pour moi.

Une façon de résoudre ce problème est de donner à Value une valeur par défaut pour getType, puis de la remplacer uniquement par KnownType. Comme si:

sealed trait Value { 
    def getType: Option[Class[_]] = None 
} 

case object UnknownValue extends Value 

case class KnownType(typ: Class[_]) extends Value { 
    override def getType = Some(typ) 
} 

Mais cela ressemble étrangement à l'idée de réinventer Option. Je passerais le type de valeur tout à fait, et juste utiliser des options droites.

Map(
    0 -> Some(classOf[Object]), 
    1 -> None) 

Si vous ne souhaitez pas taper l'option [classe [_]] chaque fois que vous vous attendez à une de ces cartes, vous pouvez créer un alias pour elle:

type Value = Option[Class[_]] 
+0

Ceci est un exemple minimal pour reproduire le problème. Dans le code réel, il existe également d'autres classes de cas, donc il ne s'agit pas simplement de réinventer Option. –

1

Il ne ressemble à une bug, mais il y a beaucoup de problèmes avec l'inférence de type qui peut facilement être travaillé en lui donnant un peu d'aide. Il compile comme ceci:

Map(
    0 -> KnownType(classOf[Object]), 
    1 -> (UnknownValue() : Value)) 
Questions connexes