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

上記のコードがまだ機能しているのはなぜですか?

4

3 に答える 3

5

scaladoc のバグのようです。object (から継承) にメソッドがありますが、Map のドキュメントには表示されません。この問題は、upcomping 2.10 のドキュメントで修正されているようです。applycollection.mutable.MapGenMapFactory

注:クラスのドキュメントではなく、オブジェクトのドキュメントを調べる必要があります。applyもちろん、このメソッドはclass既存のマップ インスタンスで動作し、そこからデータを取得します。

于 2012-07-21T16:29:45.803 に答える
3

のコンパニオン オブジェクトには apply() メソッドがありますscala.collection.immutable.Map()。から継承されscala.collection.MapFactory ます。そのメソッドは可変数のペア引数を取り、通常は次のように使用されます。

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

引数なしで呼び出すことも明らかにうまくいきますが、私よりも頭の良い誰かが、型推論エンジンがなぜそれを思いついたのかを説明する必要があるでしょうscala.collection.mutable.Map[Nothing,Nothing]

于 2012-07-21T16:30:38.470 に答える
1

sepp2k彼のコメントで既に述べたように、シンボルはMapのコンパニオン オブジェクトを参照し、Mapその単一のインスタンスにアクセスできます。パターンマッチングでは、これはメッセージを識別するためによく使用されます。

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

と書くと object のメソッドをMap()呼び出します。コンパイラに挿入する値を指定しなかったため、コンパイラは型を推測できません。したがって、すべての型のサブタイプである一番下の型を使用する必要があります。差異はありますが、型システムを壊すことのない推論可能な唯一の型です。次のコードはコンパイルされません。applyMapMapNothingNothing

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 >: BNothingはすべてのサブタイプであるため(この場合は)、コンパイラは(この場合は)Bを見つけて、Map の型シグネチャを正常に推論できます。は共変 ( source ) であるため、この下限が必要です。B1IntB

trait MapLike[A, +B, ...] ...

つまり、メソッド パラメーターとして渡すことはできません (メソッド パラメーターは反変の位置にあるため)。メソッドのパラメーターが反変の位置にない場合、Liskov の置換原則は型システムによって保持されなくなります。したがって、新しい型 (ここでは と呼ばれる) をコンパイルするコードを取得するには、B1見つけなければなりません。

Didier Dupontすでに指摘したように、Scaladoc 2.9 にはいくつかのバグがあり、2.10 で解決されています。そこにはいくつかの欠落したメソッドが表示されるだけでなく、暗黙的な変換によって追加されたメソッドも表示できます (たとえば、 Arrayは、2.9 では表示されない 2.10 の多くのメソッドを表示します)。

于 2012-07-21T16:31:56.507 に答える