考虑以下(使用 Scala 2.8.1 和 2.9.0 测试):
trait Animal
class Dog extends Animal
case class AnimalsList[A <: Animal](list:List[A] = List())
case class AnimalsMap[A <: Animal](map:Map[String,A] = Map())
val dogList = AnimalsList[Dog]() // Compiles
val dogMap = AnimalsMap[Dog]() // Does not compile
最后一行失败:
error: type mismatch;
found : scala.collection.immutable.Map[Nothing,Nothing]
required: Map[String,Main.Dog]
Note: Nothing <: String, but trait Map is invariant in type A.
You may wish to investigate a wildcard type such as `_ <: String`. (SLS 3.2.10)
Error occurred in an application involving default arguments.
val dogMap = AnimalsMap[Dog]() // Does not compile
^
one error found
更改它以val dogMap = AnimalsMap[Dog](Map())
修复它,但不再利用默认参数值。
鉴于 List 对应项按预期工作,为什么默认值被推断为 Map[Nothing,Nothing]?有没有办法创建一个使用map
arg 的默认值的 AnimalsMap 实例?
编辑:我已经接受了对我更紧迫的第二个问题的回答,但我仍然想知道为什么Map()
在这两种情况下推断的键类型不同:
case class AnimalsMap1(map:Map[String,Animal] = Map())
val dogs1 = AnimalsMap1() // Compiles
case class AnimalsMap2[A <: Animal](map:Map[String,A] = Map())
val dogs2 = AnimalsMap2[Dog]() // Does not compile
编辑2:似乎类型界限是无关紧要的 - 案例类的任何参数类型都会导致问题:
case class Map3[A](map:Map[String,A] = Map())
val dogs3 = Map3[Dog]() // Does not compile