generics - Scala 泛型 : Int not conforming to 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 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] {
    // ...
}

但以下两个不是:
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] {
    // ...
}

不同的是,我去掉了 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]]

它只是说出了点问题,但没有说哪个类型参数是错误的,以及为什么。看this question ,我想我可以尝试“ID <% Comparable[ID]”,但这在特征声明中是不合法的。

实际上,这也不起作用(带有相同的错误消息):
trait TestBase extends BaseWithID[TestBase,TestMeta,Int]

trait TestMeta extends Meta[TestBase,TestMeta,Int]

最佳答案

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

你通常会说有一个 Ordering在您的 ID 类型的隐式范围内可用,带有 ID : Ordering .

举个简单的例子:

import Ordering.Implicits._
def max[A : Ordering](x: A, y: A) : A = if (x > y) then x else y

这相当于将 Ordering(与 java.util.Comparator 相同)传递给函数。确实,宣言
def max[A : Ordering](x: A, y: A)

翻译成
def max[A](x: A, y: A)(implicit ev: Ordering[A])

在哪里 ev是一个新鲜的名字。如果 A : Ordering 出现在类上而不是方法定义上,就像在您的代码中一样,它会转换为构造函数的隐式参数,如果需要,该参数将保存在字段中,并且在类的隐式范围内可用。这比强制 A 为 Comparable 更灵活。 (Ordered 在 scala 中),因为它可能用于不属于您且未实现 Comparable 的类。您也可以在同一类的不同 Odering 之间进行选择,只要颠倒默认设置:有一个 def reverse : Ordering Ordering上的方法就是这样做的。

不利的一面是,VM 不太可能内联对比较方法的调用,但也不太可能使用泛型中的接口(interface)方法。

实现 Comparable<T> 的类型在java中自动获取Ordering通过对象 ordered 中的隐式方法 ( Ordering ) 在隐式范围内.一个java Comparator<T>也可以转换为 Ordering (Ordering.comparatorToOrdering)。

导入 Ordering.Implicits._ 可以让你得到很好的 x > y语法,当 Ordering[A]在隐式范围内。

关于generics - Scala 泛型 : Int not conforming to Comparable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6806049/

相关文章:

java - 在Java中从字符串中提取这个int的最佳方法是什么?

java - 从 Java-12 中的 switch 表达式返回通用值

swift - 泛型函数查询

java - 泛型数组的洗牌算法

scala - Kotlin 序列会缓存中间结果吗?

swift - 如何在 swift 中将 Double 舍入到最近的 Int?

java - RequestFactory:代理实现泛型接口(interface)

scala - 在 Spark JDBC 读取方法中使用谓词

scala - 如何定义一个将函数文字(带有隐式参数)作为参数的函数?

c# - Convert.ToInt32 用户输入数组转换为 int c#