Trait val 成员与抽象类型的 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] {
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 比较 that.key
但这也会失败,因为编译器认为没有定义比较。另外,是否有一种解决方案可以通过限制 K 将 compare
移动到特征键中(例如 type K <: Ordered[K]
)?
im trying to figure out how to express the below code using abstract types instead of using type parameters.
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
}
My current version looks as follows:
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]
}
But I'm not happy with the explicit casting to the type K: that.key.asInstanceOf[K]
. Are there better/other ways to achieve the ordering on an abstract member using abstract types?
I have also tried to ensure that the type of that:Key
is a Double
:
def compare(that:Key { type K = Double } ):Int = this.key compare that.key
but this also fails since the compiler doesnt think compare is defined. Also, is there a solution where compare
can be moved into the trait Key by restricting K (e.g. type K <: Ordered[K]
)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您至少需要一个类型参数来指示
DoubleKey
和StringKey
不具有可比性。写成DoubleKey(1.0) < 是没有意义的。 StringKey("foo")
根据您当前的设计,您可能会遇到类转换异常:
这是一个定义,它将在编译时强制执行约束,并将比较的定义拉入基本成员:
请注意,我使用了视图绑定,因为
Double
或String
不是 Ordered 的子类型,但有可用的隐式转换。I think you need at least one type parameter to indicate that
DoubleKey
and sayStringKey
are not comparable. It would not make sense to writeDoubleKey(1.0) < StringKey("foo")
With your current design you could get a class cast exception:
Here is a definition that will enforce the constraint at compile time and also pull the definition of compare into the base member:
Note that I used a view bound, as
Double
orString
aren't subtypes of Ordered but there are implicit conversions available.从 Key 中消除类型参数同时仍允许 Key 安全排序的唯一方法是定义从 Key 类型到 Ordered key 类型的隐式转换。这也使得分解比较方法变得简单。
示例 REPL 会话(注意:将 Trait/object Key 包装在虚拟对象中以确保 REPL 将它们视为同伴),
The only way to eliminate the type parameter from Key whilst still allowing Keys to be safely ordered is to define an implicit conversion from the Key type the the Ordered key type. This also makes it straightforward to factor out the compare method.
Sample REPL session (nb. wrap trait/object Key in a dummy object to ensure the REPL sees them as companions),