2012-07-21 59 views
3
C:\Users\John>scala 
Welcome to Scala version 2.9.2 (Java HotSpot(TM) Client VM, Java 1.6.0_32). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> import scala.collection.mutable.Map 
import scala.collection.mutable.Map 

scala> Map() 
res4: scala.collection.mutable.Map[Nothing,Nothing] = Map() 

当使用Map()而不使用关键字new时,将从相应伴随对象调用apply方法。但Scala文档没有列出可变映射的apply方法(只提供了一个apply方法从地图中检索值)。为什么不使用apply方法可以创建Map对象?

为什么上面的代码仍然有效?

+2

只要编写'Map'不会调用'apply'方法 - 它只是指类型。因此'Map'编译并不奇怪。真正的问题是为什么当你编写Map()时它仍然会编译。 – sepp2k 2012-07-21 16:17:28

+0

@ sepp2k谢谢,我更新了这个问题。 – 2012-07-21 16:21:33

回答

5

它看起来像scaladoc中的一个bug。有apply方法在对象collection.mutable.Map(从GenMapFactory继承),但它不出现在文档的地图。这个问题似乎在the doc for upcomping 2.10中得到解决。

注意:您必须查看对象文档,而不是第一类。 class中的apply方法当然适用于现有的地图实例,并从中检索数据。

3

scala.collection.immutable.Map()的伴随对象有apply()方法。它从scala.collection.MapFactory继承。该方法采用可变数量的自变量对,通常用作

Map("foo"->3, "bar"->4, "barangus"->5) 

不带任何参数显然作品,以及调用它,但有人亮度比我必须解释为什么类型推理引擎来了scala.collection.mutable.Map[Nothing,Nothing]为了它。

1

由于sepp2k在他的评论中已经提到,符号Map指的是Map的伴侣对象,它允许您访问其单个实例。在图案匹配,这是经常被用来识别一个信息:如果你写Map()您将调用对象Mapapply方法

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中)。

相关问题