Scalaの初心者として、ひびを入れるのに難しいナッツを選んだことがありますか?:-)
わかりました、簡単なツアーです。今は完全に理解することを期待しないでください。まず、問題はメソッドで発生することに注意してください++
。その定義を検索すると、特性でそれが見つかり、またはのMapLike
いずれかを受け取ります。は、であるため、使用されているバージョンです。Iterator
Traversable
y
SortedMap
Traversable
その広範な型シグネチャで、CanBuildFrom
渡されていることに注意してください。暗黙的に渡されるため、通常は心配する必要はありません。しかし、何が起こっているのかを理解するために、今回はそうします。
CanBuildFromは、の定義に表示されている場所をクリックする++
か、フィルタリングすることで見つけることができます。ランドールがコメントで述べたように、scaladocページの左上にマークされていない空白のフィールドがあります。そこをクリックして入力するだけで、入力した内容に一致するものが返されます。
したがって、CanBuildFrom
ScalaDocで特性を調べて、それを選択します。多数のサブクラスがあり、それぞれが特定のタイプのコレクションの構築を担当します。サブクラスを検索してクリックしますSortedMapCanBuildFrom
。SortedMap
これは、からを生成するために必要なオブジェクトのクラスですTraversable
。インスタンスコンストラクター(クラスのコンストラクター)については、暗黙のOrdering
パラメーターを受け取ることに注意してください。今、私たちは近づいています。
今回は、フィルターフィルターを使用してを検索しOrdering
ます。そのコンパニオンオブジェクト(名前の小さな「o」をクリック)は、Ordering
sを生成する暗黙のオブジェクトをホストします。これは、コンパニオンオブジェクトが、そのクラスのインスタンスまたは変換を生成する暗黙のオブジェクトについて検査されるためです。LowPriorityOrderingImplicits
これは、オブジェクトが拡張するトレイト内で定義され、Ordering
それを見ると、必要な...ordered[A <: Ordered[A]]
を生成するメソッド、Ordering
または問題がなければ生成するメソッドが表示されます。
これをもっと注意深く調べる前に私が持っていたように、からX
への暗黙の変換で十分だと思うかもしれません。Ordered[X]
ただし、これはオブジェクトの変換であり、のサブタイプであるタイプを受け取るordered
ことを期待しています。型のオブジェクトを型のオブジェクトに変換することはできますが、それ自体はのサブタイプではないため、パラメータとしてに渡すことはできません。Ordered[X]
X
Ordered[X]
X
Ordered[X]
ordered
一方、のval
Ordering[X]
代わりに暗黙のを作成することdef
Ordered[X]
で、問題を回避できます。具体的には:
object ViewBoundExample {
class X
def combine[Y](a: SortedMap[X, Y], b: SortedMap[X, Y]): SortedMap[X, Y] = {
a ++ b
}
implicit val orderingX = new Ordering[X] { def compare(x: X, y: X) = 0 }
}
私はほとんどの人がOrdered
/に対する最初の反応Ordering
は困惑の1つでなければならないと思います:なぜ同じことのためのクラスがあるのですか?前者はを拡張java.lang.Comparable
し、後者はを拡張しjava.util.Comparator
ます。残念ながら、の型compare
アノテーションは主な違いをほぼ要約しています。
def compare(that: A): Int // Ordered
def compare(x: T, y: T): Int // Ordering
の使用には、の定義を変更できるようにする必要があるを拡張するOrdered[A]
か、をに変換できるメソッドを渡す必要があります。Scalaは後者を簡単に実行できますが、比較する前に各インスタンスを変換する必要があります。A
Ordered[A]
A
A
Ordered[A]
一方、を使用するにOrdering[A]
は、上記のように単一のオブジェクトを作成する必要があります。これを使用するときは、タイプの2つのオブジェクトを渡すだけですA
。compare
プロセスでオブジェクトは作成されません。
Ordering
そのため、パフォーマンスが向上する可能性がありますが、Scalaがoverを好む理由ははるかに重要Ordered
です。コンパニオンオブジェクトをもう一度見てくださいOrdering
。そこに定義されているScalaクラスの多くにはいくつかの暗黙的なものがあることに気付くでしょう。T
のコンパニオンオブジェクト内で暗黙のforクラスが検索されることを前述したことを思い出してくださいT
。これが、まさに起こっていることです。
これも同様に行うことができます。Ordered
ただし、これが問題です。つまり、両方Ordering
をサポートするすべてのメソッドOrdered
が失敗します。これは、Scalaがそれを機能させるために暗黙的なものを探し、2つを見つけるためです。1つは、、Ordering
もう1つはOrdered
。どちらが必要かを判断できないため、Scalaはエラーメッセージを表示します。それで、選択がなされなければならなかった、そしてOrdering
それのためにもっと進んでいました。
ordered[A <% Ordered[A]]
ええと、署名が。ではなく、として定義されていない理由を説明するのを忘れましたordered[A <: Ordered[A]]
。そうすることで、前述の二重暗黙の失敗が発生するのではないかと思いますが、実際にこのようなことを行い、二重暗黙の問題を抱えていた人に、この特定の方法に問題があるかどうかを尋ねます。