Pourquoi le code Scala suivant ne compile-t-il que si des paramètres de type explicite sont ajoutés?

StackOverflow https://stackoverflow.com/questions/1038183

  •  10-07-2019
  •  | 
  •  

Question

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)
}

La compilation du code ci-dessus a échoué. Le message d'erreur du compilateur est le suivant:

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 en def getType: Option [Class [_]] = None , la compilation Map () sans paramètre de type est également compilée.

Pourquoi?

Était-ce utile?

La solution 3

J'ai posté la question sur la liste de diffusion de scala-user et ils ont également dit qu'il s'agissait d'un bug.

Autres conseils

Hmm, c'est bizarre. Ça ressemble à un bug pour moi.

Vous pouvez résoudre ce problème en donnant à Value une valeur par défaut pour getType, puis en le remplaçant uniquement dans 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 à une réinvention d'Option. Je saute complètement le type de valeur et n'utilise que des options droites.

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

Si vous n'aimez pas taper Option [Class [_]] chaque fois que vous attendez l'une de ces cartes, vous pouvez créer un alias pour cette dernière:

type Value = Option[Class[_]]

Cela ressemble à un bogue, mais il existe de nombreux problèmes avec l’inférence de type qui peuvent facilement être contournés en lui donnant un peu d’aide. Il compile comme ceci:

Map(
  0 -> KnownType(classOf[Object]),
  1 -> (UnknownValue() : Value))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top