Generics trait val成员与抽象类型的Scala比较
我试图弄明白如何用抽象类型而不是类型参数来表达下面的代码Generics trait val成员与抽象类型的Scala比较,generics,scala,Generics,Scala,我试图弄明白如何用抽象类型而不是类型参数来表达下面的代码 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] {
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]
。是否有更好的/其他的方法来使用抽象类型实现对抽象成员的排序
我还尝试确保的类型为:Key
是Double
:
def compare(that:Key{type K=Double}):Int=this.Key比较that.Key
但这也失败了,因为编译器认为没有定义比较。此外,是否有一种解决方案,通过限制K(例如,
类型K我认为您至少需要一个类型参数来指示DoubleKey
和说StringKey
不可比较。编写DoubleKey(1.0)
使用当前设计,您可能会遇到类强制转换异常:
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
case类StringKey(val-key:String)扩展键{
类型K=字符串
def compare(that:Key):Int=this.Key比较that.Key.asInstanceOf[K]
}
StringKey(“b”)
下面是一个定义,它将在编译时强制执行约束,并将compare的定义拉入基本成员:
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
abstract class Key[K在允许密钥安全排序的同时,从Key中删除type参数的唯一方法是定义从Key类型到ordered Key类型的隐式转换。这也使得比较方法变得简单
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 }
trait Key{type K;val Key:K}
对象键{
类型PKey[KK]=Key{type K=KK}
隐式def KEYSORDED[K双键(23)<双键(34)
res3:Boolean=true
scala>StringKey(“foo”)StringKey(“foo”)
我建议完全避免在此处进行排序,并提供隐式对象进位排序[DoubleKey]。这使事情变得更简单……感谢您的回答!它比“已接受”的更简洁。
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)