2012-09-22 58 views
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的成员

我怎么能说是和这是相同的类型?或者我在尝试不可能的事情?

回答

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,有两两件事必须持有。

  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 
+0

这正是我想要做的。谢谢:) – Eduardo

0

一个更好的办法是遵循标准库中OrderedOrdering特质发挥出来。前者就像你上面的例子。但事实证明,使用“类型类”的后者更容易且更灵活。

首先,定义一个类类和混入特质:现在

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为一类,并使用隐式转换,但是这是这个答案范围之外的一点,所以我写这here

+0

但我需要一个案例类而不是一个类,对吧? – Eduardo

+0

@Eduardo案例类仅仅是为了方便实例化。在REPL中像正常的类一样尝试。 –

+0

我尝试使用一个简单的类,但它没有工作。 – Eduardo

相关问题