2

他の演算子に基づいて演算子を記述する特性を定義しようとしています。このようなもの:

trait LessThanComparable[T] {
    def < (that: T) : Boolean

    def > (that: T) = that < this
}

それから私はそれを使います:

class Example(val x : Int) extends LessThanComparable[Example] {
    def < (that: Example) = x < that.x
}

しかし、私はこれを取得します:値<はタイプパラメータTのメンバーではありません

それとこれは同じタイプであるとどうやって言うことができますか?それとも私は不可能なことを試みていますか?

4

2 に答える 2

2

私はこれがあなたが望むものだと思います:

trait LessThanComparable[T <: LessThanComparable[T]] { this: T =>
  def <(that: T): Boolean

  def >(that: T) = that < this
}

class Example(val x: Int) extends LessThanComparable[Example] {
  def <(that: Example) = x < that.x
}

言うことができるためにはthat < this、2つのことが成り立つ必要があります。

  1. that<を受け入れるメソッドを持っている必要があります。Tつまり、であるthat必要がありLessThanComparable[T]ます。Tこれは、LessThanComparable[T]のサブクラスである必要があると言うことで保証できT <: LessThanComparable[T]ます。

  2. thisである必要がありますT。セルフタイプを使用することでこれを保証できthis: T =>ます。

それで、

val a = new Example(5)
val b = new Example(4)

println(a < b)  // false
println(a > b)  // true
println(b < a)  // true
println(b > a)  // false
于 2012-09-22T01:15:51.603 に答える
0

より良いアプローチは、標準ライブラリのOrderedと特性で実行されたものに従うことです。Ordering前者は上記の例のようなものです。しかし、代わりに「型クラス」を使用する後者の方が簡単で柔軟性が高いことがわかりました。

まず、型クラスとミックスイン特性を定義します。

class Ord[T](val lessThan: (T, T) => Boolean)

trait CompareOps[T] { this: T =>
  def < (that: T)(implicit ord: Ord[T]) = ord.lessThan(this, that)
  def > (that: T)(implicit ord: Ord[T]) = ord.lessThan(that, this)
}

さて、あなたの例では、あなたがしなければならないのはあなたの型クラスのインスタンスを暗黙のスコープに置くことだけです:

case class Example(x: Int) extends CompareOps[Example]

implicit val exampleOrd = new Ord[Example](_.x < _.x)

scala> Example(3) > Example(4)
res0: Boolean = false

scala> Example(3) < Example(4)
res1: Boolean = true

通常、クラスを作成するときは、のコンパニオンオブジェクトOrd[Example]を入れます。その後、インスタンスが必要とするExampleときに、自動的に暗黙のスコープになります。Example

CompareOps余談ですが、クラスとして定義して暗黙の変換を使用する場合は、実際に拡張する必要はありませんがCompareOps、それはこの回答の範囲外なので、 ここに記述しました。

于 2012-09-22T04:03:35.457 に答える