明示的な型パラメーターを追加しないと、次のScalaコードがコンパイルされないのはなぜですか?

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

  •  10-07-2019
  •  | 
  •  

質問

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

scala-userメーリングリストに質問を投稿しましたが、彼らはそれがバグだと言っていました。

他のヒント

うーん、それは奇妙です。私にはバグのように見えます。

これを修正する1つの方法は、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[_]]

これはバグのように見えますが、型推論には多くの問題があり、少し助けを与えることで簡単に回避できます。次のようにコンパイルされます:

Map(
  0 -> KnownType(classOf[Object]),
  1 -> (UnknownValue() : Value))
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top