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()。
为什么?
答案 0 :(得分:2)
您可以解决的一种方法是为Value提供一个默认值,然后只在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)
如果您不希望每次预期其中一个地图时键入选项[类[_]],则可以为其创建别名:
type Value = Option[Class[_]]
答案 1 :(得分:1)
它确实看起来像一个错误,但是类型推断有很多问题,可以通过给它一些帮助来轻松解决。它编译如下:
Map(
0 -> KnownType(classOf[Object]),
1 -> (UnknownValue() : Value))
答案 2 :(得分:1)
我将问题发布到scala-user邮件列表,他们也说这是一个错误。