明示的な型パラメーターを追加しないと、次のScalaコードがコンパイルされないのはなぜですか?
-
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))
所属していません StackOverflow