初学者:我怎么说“任何超类通用A”

时间:2012-01-20 18:06:49

标签: generics scala

我正在使用Scala By Example开头的QuickSort示例,并尝试将其调整为通用类型A,而不仅仅是Int

到目前为止我的工作是

def sort[A <: Ordered[A]](xs: Array[A]) 

允许sort在所有反复排序的类型上运行,RichBoolean

但我还想允许类型A扩展Ordered[B],其中B是A的超类(例如,扩展Ordered[Any]的任何内容)。< / p>

我该怎么说?


由于agilesteel's answer

,我实际上需要工作
case class X( i : Int ) extends Ordered[X] {
  def compare( x : X ) = x.i - i
}

class Y( i : Int, j : Int ) extends X(i)

case class Z( i : Int ) extends Ordered[Any] {
  def compare( a : Any ) : Int = {
    if (! a.isInstanceOf[Z] ) 
      sys.error("whoops") 

    val z = a.asInstanceOf[Z]
    z.i - i
  }
}

object QuickSort {
  def main( args : Array[String] ) {
    val xs = Array( 3, 1, 2, 4 ) map X
    sort( xs );
    val ys = Array( 3, 1, 2, 4 ) map { i => new Y(i, -i) }
    sort[X,Y]( ys );
    val zs = Array( 3, 1, 2, 4 ) map Z
    sort[Any,Z]( zs );
  }
  def sort[B >: A, A <: Ordered[B]](xs: Array[A]) {
    def swap(i: Int, j: Int) {
      val t = xs(i); xs(i) = xs(j); xs(j) = t;
    }
    def sort1(l: Int, r: Int) {
      val pivot = xs((l + r) / 2)
        var i = 1; var j = r
      while (i <= j) {
        while (xs(i) < pivot) i += 1
        while (xs(j) > pivot) j -= 1
        if (i <= j) {
          swap(i, j)
          i += 1
          j += 1
        }
      }
      if (l < j) sort1(l, j)
      if (j < r) sort1(i, r)
    }
    sort1(0, xs.length - 1)
  }
}

我试图使用RichLongRichBoolean作为测试类型而被误导,因为它们并非真正反射Ordered(它们扩展Ordered[Long]和{{1}而不是)。

2 个答案:

答案 0 :(得分:7)

这样的东西?

def sort[B >: A, A <: Ordered[B]](xs: Array[B]) 

答案 1 :(得分:1)

您正在寻找的东西要么来自Ordered特征,要么可以被视为特征。从许多类到Ordered有很多隐式转换(称为视图),你也可以拥有自己的转换。但是,你最终得到:

def sort[A <% Ordered[A]](xs: Array[A]) = ...

<%只是def sort(xs: Array[A])(implicit cv: A => Ordered[A]) = ...的语法糖。如果你对隐含的幕后情况感兴趣,你可能想看看这个很好的compilation问题和答案。