由于sepp2k
在他的评论中已经提到,符号Map
指的是Map
的伴侣对象,它允许您访问其单个实例。在图案匹配,这是经常被用来识别一个信息:如果你写Map()
您将调用对象Map
的apply
方法
scala> case object Foo
defined module Foo
scala> def send[A](a: A) = a match { case Foo => "got a Foo" case Map => "got a Map" }
send: [A](a: A)String
scala> send(Map)
res8: String = got a Map
scala> send(Foo)
res9: String = got a Foo
。由于您没有给出任何值来插入到Map
编译器不能推断任何类型,因此它必须使用bottom type - Nothing
- 这是每种类型的子类型。这是唯一可能的类型来推断哪些不会破坏类型系统,尽管存在差异。将Nothing
不存在下面的代码将无法编译:
scala> Map(1 -> 1) ++ Map()
res10: scala.collection.mutable.Map[Int,Int] = Map(1 -> 1)
如果你看看到的++
类型签名是如下(source)
def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): Map[A, B1]
你会发现下限键入参数B1 >: B
。因为Nothing
是一切的子类型(在我们的例子中为B
),编译器可以找到一个B1
(在我们的例子中为Int
)并成功推断出我们的Map的类型签名。此结合的下需要因为B
是协变(source)
trait MapLike[A, +B, ...] ...
这意味着我们不能读出它作为方法参数(因为方法参数在逆变位置)。如果方法参数不在逆向位置Liskov's substitution principle将不再由类型系统保存。因此必须找到代码来编译一个新类型(这里称为B1
)。
由于Didier Dupont
已经指出Scaladoc 2.9中存在一些bug,这些bug在2.10中解决。不仅有一些错过的方法显示在那里,而且还可以显示通过隐式转换添加的方法(例如,在2.10中显示很多方法,但不显示在2.9中)。
只要编写'Map'不会调用'apply'方法 - 它只是指类型。因此'Map'编译并不奇怪。真正的问题是为什么当你编写Map()时它仍然会编译。 – sepp2k 2012-07-21 16:17:28
@ sepp2k谢谢,我更新了这个问题。 – 2012-07-21 16:21:33