斯卡拉特质VAL成员的比较抽象类型
即时试图找出如何使用抽象类,而不是使用类型参数来表达下面的代码。斯卡拉特质VAL成员的比较抽象类型
trait Key[T] extends Ordered[Key[T]] {
val key:T
}
case class DoubleKey(key:Double) extends Key[Double] {
def compare(that:Key[Double]):Int = this.key compare that.key
}
我目前的版本看起来如下:
trait Key extends Ordered[Key] {
type K
val key:K
}
case class DoubleKey(val key:Double) extends Key {
type K = Double
def compare(that:Key):Int = this.key compare that.key.asInstanceOf[K]
}
但我不愉快的显式转换为类型K:that.key.asInstanceOf[K]
。使用抽象类型有什么更好/其他方法来实现抽象成员的排序?
我也试图确保that:Key
类型是Double
:
def compare(that:Key { type K = Double }):Int = this.key compare that.key
但由于犯规觉得比较定义编译器,这也将失败。此外,是否有解决方案compare
可以通过限制K(例如type K <: Ordered[K]
)转移到特征密钥?
,以消除重点,同时仍允许密钥安全地订购的类型参数的唯一方法是定义从主要类型的有序密钥类型的隐式转换。这也使得比较方法的分解变得简单。
trait Key { type K ; val key : K }
object Key {
type PKey[KK] = Key { type K = KK }
implicit def keyIsOrdered[K <% Ordered[K]](lhs : PKey[K]) = new Ordered[PKey[K]] {
def compare(rhs : PKey[K]) = lhs.key compare rhs.key
}
}
case class DoubleKey(val key : Double) extends Key { type K = Double }
case class StringKey(val key : String) extends Key { type K = String }
我建议样品REPL会话(特别注意:包装特质/对象键在虚拟对象,以确保REPL看到他们为同伴),
scala> DoubleKey(23) < DoubleKey(34)
res3: Boolean = true
scala> StringKey("foo") < StringKey("bar")
res4: Boolean = false
scala> StringKey("foo") < DoubleKey(23)
<console>:14: error: could not find implicit value for parameter ord: scala.math.Ordering[ScalaObject]
StringKey("foo") < DoubleKey(23)
我认为你需要至少一种类型的参数来表示DoubleKey
说StringKey
没有可比性。这是没有意义的写DoubleKey(1.0) < StringKey("foo")
根据您目前的设计,你可以得到一个类转换异常:
case class StringKey(val key:String) extends Key {
type K = String
def compare(that:Key):Int = this.key compare that.key.asInstanceOf[K]
}
StringKey("b") < DoubleKey(1.0) // ClassCastException
这里是将强制约束在编译的时候,也拉动比较的定义的定义到基部构件:
abstract class Key[K <% Ordered[K]] extends Ordered[Key[K]] {
val key:K
def compare(that:Key[K]): Int = key compare that.key
}
case class DoubleKey(key:Double) extends Key[Double]
case class StringKey(key:String) extends Key[String]
StringKey("b") < DoubleKey(1.0) // won't compile
注意,我使用的结合的图,作为Double
或String
不亚型有序,但也有隐式转换。
感谢您的回答!它比“接受”更简洁。 – Malcolm 2014-04-20 00:43:21
完全避免这里有序,并提供一个隐含的对象,参与排序[DoubleKey]。这使事情变得更容易... – Landei 2011-01-05 15:01:27