3

今、私は混乱しています。私は Scala を初めて使用し、数週間使用してきたので、慣れてきたと思いますが、明らかに些細な次のケースで立ち往生しています。

この Java 宣言に相当する Scala が見つかりません。

public static <T extends Comparable<T>> List<T> myMethod(List<T> values) {
  // ...
  final List<T> sorted = new ArrayList<T>(values);
  Collections.sort(sorted);
  // ...
}

私は次のことができると思いました:

def myMethod[A >: Ordering[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}

ただし、次のエラーが発生します。

エラー: タイプ A を含む不正な循環参照です

エラー: オブジェクト Ordering のメソッド Tuple9 で始まる型 scala.math.Ordering[A] の暗黙的な展開の発散

どこが間違っていますか?

4

2 に答える 2

7

まず第一に、Orderingは に似ておりComparator、 ではありませんComparable。に相当する ScalaComparableは ですOrdered。次に、extends同値は<:であり、 ではありません>:super後者は--と同等ですがT super COmparable<T>、これはあなたが望むものではありません。したがって、これらの両方の修正を行うと、コードは次のようになります。

def myMethod[A <: Ordered[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}

ただし、Seq[Int]たとえば、Intは拡張されないため、これは機能しませんOrdered。Javaintが拡張しないのと同じようにComparable(または、クラスではないため、他の何か)。

Scala にはそのための回避策があります。特定のクラスからクラスへの暗黙的な変換Orderedです。ただし、それを使用するには、ビュー バウンドを使用する必要があります。これにより、コードは次のようになります。

def myMethod[A <% Ordered[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}

<%の代わりに参照してください<:。それがビューバウンドです。

現在、Scala サークルの現在の優先事項は、ビュー境界の代わりにコンテキスト境界を使用することです。コンテキスト境界の方がより柔軟です。Orderingそれは、他の回答で説明されている方法で、を使用することを意味します。

于 2011-05-31T18:01:23.053 に答える
5

以下に示すように、これはコンテキスト バインドである必要があります。

scala> def myMethod[A : Ordering](values: Seq[A]): Seq[A] = values.sorted
myMethod: [A](values: Seq[A])(implicit evidence$1: Ordering[A])Seq[A]
于 2011-05-31T13:49:23.043 に答える