Seb*_*iot 5 generics int scala 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 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] {
// ...
}
Run Code Online (Sandbox Code Playgroud)
但以下两个不是:
trait BaseWithIntID[B <: BaseWithIntID[B,M], M <: MetaWithIntID[B,M]] extends BaseWithID[B,M,Int] {
// ...
}
trait MetaWithIntID[B <: BaseWithIntID[B,M], M <: MetaWithIntID[B,M]] extends Meta[B,M,Int] {
// ...
}
Run Code Online (Sandbox Code Playgroud)
不同之处在于我删除了BaseWithIntID和MetaWithIntID中的ID类型参数,并在各自的基本特征中明确指定了Int.但是这不能编译,那么这是否意味着Int在Scala中不可比较?如果是的话,我做错了什么?我尝试了Ordered而不是Comparable,它没有区别.
我正在使用Eclipse,并且像往常一样,错误消息是无益的:
type arguments [B,M,Int] do not conform to trait BaseWithID's type parameter bounds [B <: BaseWithID[B,M,ID],M <: Meta[B,M,ID],ID <: java.lang.Comparable[ID]]
Run Code Online (Sandbox Code Playgroud)
它只是说有些东西是错的,但不是哪种类型参数是错误的,为什么呢.看看这个问题,我想我可以尝试"ID <%Comparable [ID]",但这在特质声明中是不合法的.
实际上,这也不起作用(使用相同的错误消息):
trait TestBase extends BaseWithID[TestBase,TestMeta,Int]
trait TestMeta extends Meta[TestBase,TestMeta,Int]
Run Code Online (Sandbox Code Playgroud)
在scala中,Int确实不具有可比性,当然因为它实际上是作为java实现的int,而不是java.lang.Integer.我不确定那是不可能的,C#struct(值类型)可以实现接口,但这不是在这里完成的.
你通常做的是说Ordering你的ID类型的隐式范围可用ID : Ordering.
举个简单的例子:
import Ordering.Implicits._
def max[A : Ordering](x: A, y: A) : A = if (x > y) then x else y
Run Code Online (Sandbox Code Playgroud)
这相当于将Ordering(与a相同java.util.Comparator)传递给函数.确实,宣言
def max[A : Ordering](x: A, y: A)
Run Code Online (Sandbox Code Playgroud)
翻译成
def max[A](x: A, y: A)(implicit ev: Ordering[A])
Run Code Online (Sandbox Code Playgroud)
哪里ev是新名字.如果A:Ordering出现在类而不是方法定义中,就像在代码中一样,它会转换为构造函数的隐式参数,如果需要,它将保存在字段中,并且可以在类的隐式作用域中使用.这比强制A Comparable(Ordered在scala中)更灵活,因为它可能用在不属于你的类并且没有实现Comparable的类上.你也可以在同一个类中选择不同的Odering,如果只是颠倒默认的那个:有一个def reverse : Ordering方法Ordering可以做到这一点.
从糟糕的一面来看,VM不太可能内联对比较方法的调用,但它不太可能是泛型中的接口方法.
Comparable<T>在java 中实现的类型 Ordering通过ordered对象中的隐式方法()自动获得隐式范围Ordering.java Comparator<T>也可以转换为Ordering(Ordering.comparatorToOrdering).
x > y当一个Ordering[A]处于隐式作用域时,导入Ordering.Implicits._允许你使用漂亮的语法.