我在Scala By Example开始时使用QuickSort示例,并试图将其调整为泛型类型A
,而不仅仅是Int
s。
到目前为止,我的工作是
def sort[A <: Ordered[A]](xs: Array[A])
这允许sort
在反射排序的所有类型上运行,例如 .RichBoolean
但是我也想允许类型A
它们扩展的地方Ordered[B]
其中 B 是 A 的超类(因此,例如,任何扩展Ordered[Any]
的东西(。
怎么说呢?
我真正开始工作,多亏了敏捷钢的回答:
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)
}
}
我试图使用 RichLong
和 RichBoolean
作为测试类型被误导了,因为它们实际上并不是反射性地Ordered
(它们扩展了Ordered[Long]
和Ordered[Boolean]
(。
像这样的东西?
def sort[B >: A, A <: Ordered[B]](xs: Array[B])
你正在寻找的东西要么来自Ordered
特征,要么可以这样看待。从许多类到Ordered
有很多隐式转换(称为视图(,你也可以拥有自己的。但是,您最终会得到:
def sort[A <% Ordered[A]](xs: Array[A]) = ...
<%
只不过是def sort(xs: Array[A])(implicit cv: A => Ordered[A]) = ...
的句法糖。你可能想看看这个很好的问题和答案汇编,如果你对隐式幕后发生的事情感兴趣。