Generics Scala泛型:Int不符合Comparable?

Generics Scala泛型:Int不符合Comparable?,generics,scala,int,comparable,Generics,Scala,Int,Comparable,以下Scala声明是可以的: trait Base[B <: Base[B,M,ID], M <: Meta[B,M,ID], ID <: Comparable[ID]] { // ... } trait Meta[B <: Base[B,M,ID], M <: Meta[B,M,ID], ID <: Comparable[ID]] extends Ordered[Meta[_,_,_]] { // ... } trait BaseWith

以下Scala声明是可以的:

trait Base[B <: Base[B,M,ID], M <: Meta[B,M,ID], ID <: Comparable[ID]] {
    // ...
}

trait Meta[B <: Base[B,M,ID], M <: Meta[B,M,ID], ID <: Comparable[ID]] extends Ordered[Meta[_,_,_]] {
    // ...
}

trait BaseWithID[B <: BaseWithID[B,M,ID], M <: Meta[B,M,ID], ID <: Comparable[ID]] extends Base[B,M,ID] with Ordered[B] {
    // ...
}


trait BaseWithIntID[B <: BaseWithIntID[B,M,ID], M <: MetaWithIntID[B,M,ID], ID <: Comparable[ID]] extends BaseWithID[B,M,ID] {
    // ...
}

trait MetaWithIntID[B <: BaseWithIntID[B,M,ID], M <: MetaWithIntID[B,M,ID], ID <: Comparable[ID]] extends Meta[B,M,ID] {
    // ...
}
“这是否意味着Int在Scala中不可比较?”的答案显然是肯定的,因为如果我用java.lang.Integer替换Int,那么它编译时不会出错。问题是,每次访问ID时,我都必须创建一个包装器对象,这将经常发生,因此代价高昂

我想指定ID是可比较的/有序的,这样我就可以对BaseWithID本身进行排序,并使用可比较的ID在其中显式定义比较方法


目前的解决方案似乎是不指定ID是有序的,而是让具体类实现自身比较,而不是在trait中一次性实现它。有谁有更好的解决方案吗?

Int在scala中确实是不可比的,因为它实际上是作为java
Int
实现的,而不是
java.lang.Integer
。我不确定这是不可能的,C#
struct
(值类型)可以实现接口,但这里没有实现

您通常会说,在ID类型的隐式作用域中有一个
排序
,使用
ID:Ordering

举个简单的例子:

import Ordering.Implicits._
def max[A : Ordering](x: A, y: A) : A = if (x > y) then x else y
这相当于将排序(与
java.util.Comparator
相同)传递给函数。事实上,《宣言》

def max[A : Ordering](x: A, y: A)
转化为

def max[A](x: A, y: A)(implicit ev: Ordering[A])
其中,
ev
是一个新名称。如果:Ordering出现在类而不是方法定义上,就像在代码中一样,它将转换为构造函数的隐式参数,如果需要,该参数将保留在字段中,并在类的隐式范围中可用。这比强制A具有可比性(
在scala中排序)更灵活,因为它可以用于非您的类,并且没有实现可比性。您也可以在同一类上的不同排序之间进行选择,如果只需反转默认的排序:在
排序
上有一个
def reverse:Ordering
方法,它就是这样做的

坏的方面是,VM不太可能内联调用比较方法,但在泛型中使用接口方法也不太可能

在java中实现
Comparable
的类型通过对象
排序
中的隐式方法(
ordered
)在隐式范围内自动获得
排序
。java
比较器
也可以转换为
排序
排序.比较器排序

导入Ordering.Implicits.\uu当
排序[A]
在隐式范围内时,允许使用nice
x>y
语法

为了补充我的答案,在“昂贵”方面,对比较方法Ordering.comare(x,y)的调用可能不会内联,您可能也需要付费。因此,在java中,它将具有可比性。另一方面,可以调用x>y的包装意味着新的order.Ops(x)。>(y),从实现的角度来看,它是新的Ordering.Ops(ord,x),其中ord是排序。很可能可以避免创建此对象。如果需要(基准测试),您可以直接调用ordering.compare,这不会比在java.P.S中调用compare更糟糕。“可能避免创建此对象”表示“可能VM实际上不会创建此对象”。这不仅是可能的,而且可以肯定的是,您可以通过不使用x>y语法来避免对象的创建
import Ordering.Implicits._
def max[A : Ordering](x: A, y: A) : A = if (x > y) then x else y
def max[A : Ordering](x: A, y: A)
def max[A](x: A, y: A)(implicit ev: Ordering[A])