我正在尝试使用带有DateTime(joda)的> =,>等等,我能让它工作的唯一方法就是使用这种隐式转换
implicit def dateTime2ordered(x: DateTime): Ordered[DateTime] =
new Ordered[DateTime] with Proxy {
val self = x
def compare(y: DateTime): Int = {
x.compareTo(y)
}
}
我希望使用更通用的表单,例如
implicit def comparable2ordered[A <: Comparable[A]](x: A): Ordered[A] =
new Ordered[A] with Proxy {
val self = x
def compare(y: A): Int = {
x.compareTo(y)
}
}
但编译器无法找到此转换,并且在尝试直接调用它之后,我得到以下消息声称DateTime不是Comparable类型[A]。检查DateTime的源代码后,我发现它只将Comparable实现为原始类型。
我能够使用
使其工作 implicit def comparable2ordered[A <: Comparable[_]](x: A): Ordered[A] =
new Ordered[A] with Proxy {
val self = x
def compare(y: A): Int = {
x.compareTo(y)
}
}
我的问题是:这是对此问题的正确Scala处理方式,还是通配符类型绑定会导致类型检查的未来问题?
答案 0 :(得分:7)
我偶然发现了这个问题,因为我也希望使用关系运算符来比较joda DateTime对象。
丹尼尔的回答指出了我正确的方向:scala.math.Ordered
中的含义会将A extends java.lang.Comparable[A]
的实例转换为Ordered[A]
- 它们只需要被纳入范围。最简单的方法(我学习here,顺便说一句)是使用implicitly
方法:
val aOrdering = implicitly[Ordering[A]]
import aOrdering._
问题是org.joda.time.DateTime
不会扩展或实施Comparable
本身,它({间接)从org.joda.time.ReadableInstant
继承, 扩展{{1} }}。所以这个:
Comparable
将无法编译,因为val dateTimeOrdering = implicitly[Ordering[DateTime]]
import dateTimeOrdering._
未展开DateTime
。要在Comparable[DateTime]
上使用Ordered
的关系运算符,您必须改为:
DateTime
有效,因为val instantOrdering = implicitly[Ordering[ReadableInstant]]
import instantOrdering._
扩展了ReadableInstant
,Comparable[ReadableInstant]
中的隐式转化可以将其转换为Ordered
。
到目前为止,这么好。但是,有些情况下Ordered[ReadableInstant]
不够好。 (我遇到的是ScalaTest的greater and less than Matchers。)为了获得Ordered[ReadableInstant]
,我被迫这样做:
Ordered[DateTime]
似乎应该有一种更简单的方式,但我无法想出一个。
答案 1 :(得分:3)
很好,原始类型“Comparable”在Scala中被翻译为“Comparable [_]”。
它们被称为存在类型,可比较[_]是“可比较[T] forSome {类型T}”的简写(自2.7版本见http://www.scala-lang.org/node/43)
另请参阅http://www.artima.com/scalazine/articles/scalas_type_system.html
中的“存在类型”答案 2 :(得分:2)
看,事情是,这已经存在。好吧,有点......如果你看一下内部对象Ordered
,在那里寻找隐式转换,你会发现:
implicit def orderingToOrdered [T] (x: T)(implicit ord: Ordering[T]) : Ordered[T]
因此,只要有Ordering[T]
可用,就可以生成Ordered[T]
。现在,要在Ordering[T]
对象中查找Ordering
:
implicit def ordered [A] (implicit arg0: (A) ⇒ Comparable[A]) : Ordering[A]
因此,如果您将comparable: A with Comparable[A]
传递给期待Ordered[A]
的内容,则会执行此操作:
Ordered.orderingToOrdered(comparable)(Ordering.ordered(Predef.identity(comparable)))
现在,关于你的问题:使用存在类型是处理Java原始类型的正确方法。理论上,这可能导致错误的排序,但实际上,极不可能。但是,可能存在隐式歧义问题,因为Scala已经进行了Comparable => Ordered
隐式转换,如上所示。