Scalaの初心者として、ひびを入れるのに難しいナッツを選んだことがありますか?:-)
わかりました、簡単なツアーです。今は完全に理解することを期待しないでください。まず、問題はメソッドで発生することに注意してください++。その定義を検索すると、特性でそれが見つかり、またはのMapLikeいずれかを受け取ります。は、であるため、使用されているバージョンです。IteratorTraversableySortedMapTraversable
その広範な型シグネチャで、CanBuildFrom渡されていることに注意してください。暗黙的に渡されるため、通常は心配する必要はありません。しかし、何が起こっているのかを理解するために、今回はそうします。
CanBuildFromは、の定義に表示されている場所をクリックする++か、フィルタリングすることで見つけることができます。ランドールがコメントで述べたように、scaladocページの左上にマークされていない空白のフィールドがあります。そこをクリックして入力するだけで、入力した内容に一致するものが返されます。
したがって、CanBuildFromScalaDocで特性を調べて、それを選択します。多数のサブクラスがあり、それぞれが特定のタイプのコレクションの構築を担当します。サブクラスを検索してクリックしますSortedMapCanBuildFrom。SortedMapこれは、からを生成するために必要なオブジェクトのクラスですTraversable。インスタンスコンストラクター(クラスのコンストラクター)については、暗黙のOrderingパラメーターを受け取ることに注意してください。今、私たちは近づいています。
今回は、フィルターフィルターを使用してを検索しOrderingます。そのコンパニオンオブジェクト(名前の小さな「o」をクリック)は、Orderingsを生成する暗黙のオブジェクトをホストします。これは、コンパニオンオブジェクトが、そのクラスのインスタンスまたは変換を生成する暗黙のオブジェクトについて検査されるためです。LowPriorityOrderingImplicitsこれは、オブジェクトが拡張するトレイト内で定義され、Orderingそれを見ると、必要な...ordered[A <: Ordered[A]]を生成するメソッド、Orderingまたは問題がなければ生成するメソッドが表示されます。
これをもっと注意深く調べる前に私が持っていたように、からXへの暗黙の変換で十分だと思うかもしれません。Ordered[X]ただし、これはオブジェクトの変換であり、のサブタイプであるタイプを受け取るorderedことを期待しています。型のオブジェクトを型のオブジェクトに変換することはできますが、それ自体はのサブタイプではないため、パラメータとしてに渡すことはできません。Ordered[X]XOrdered[X]XOrdered[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は後者を簡単に実行できますが、比較する前に各インスタンスを変換する必要があります。AOrdered[A] AAOrdered[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]]。そうすることで、前述の二重暗黙の失敗が発生するのではないかと思いますが、実際にこのようなことを行い、二重暗黙の問題を抱えていた人に、この特定の方法に問題があるかどうかを尋ねます。