2009-06-24 23 views
2
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) 
} 

上述代码无法编译。编译器的错误信息是:为什么下面的Scala代码不能编译,除非显式的类型参数被添加?

 
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再也不用类型参数地图()编译。

为什么?

回答

1

我把问题发布到scala用户邮件列表,他们也说这是一个错误。

2

嗯,那很奇怪。对我来说看起来像一个bug。

你可以修复它的一种方法是给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) 
} 

但是这看起来很像你重塑选项。我会完全忽略Value类型,只使用直选项。

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

如果你不喜欢打字选项[类[_]每次想到这些地图的一个时间,你可以为它创建一个别名:

type Value = Option[Class[_]] 
+0

这是重现问题的最小示例。在真实的代码中还有其他的案例类,所以它不仅仅是重新发明Option。 – 2009-06-24 23:35:40

1

它看起来像一个错误,但是类型推断存在很多问题,可以通过给予一些帮助轻松解决。它编译是这样的:

Map(
    0 -> KnownType(classOf[Object]), 
    1 -> (UnknownValue() : Value)) 
相关问题