Почему следующий код Scala не компилируется, если не добавлены явные параметры типа? - PullRequest
2 голосов
/ 24 июня 2009
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)
}

Приведенный выше код не компилируется. Сообщение об ошибке компилятора:

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

Если я изменю объявление метода UnknownValue на def getType: Option[Class[_]] = None, то также компилируется Map () без параметров типа.

Почему?

Ответы [ 3 ]

2 голосов
/ 25 июня 2009

Хм, это странно. Выглядит как ошибка для меня.

Один из способов исправить это - присвоить Value значение по умолчанию для getType, а затем переопределить его только в KnownType. Вот так:

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

Но это выглядит подозрительно, как будто вы заново изобретаете Option. Я бы вообще пропустил тип Value и просто использовал бы прямые параметры.

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

Если вам не нравится вводить Option [Class [_]] каждый раз, когда вы ожидаете одну из этих Карт, вы можете создать для нее псевдоним:

type Value = Option[Class[_]]
1 голос
/ 25 июня 2009

Я отправил вопрос в список рассылки пользователей scala, а также они сказали, что это ошибка.

1 голос
/ 25 июня 2009

Это похоже на ошибку, но есть много проблем с выводом типа, которые можно легко обойти, если немного помочь. Компилируется так:

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