加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何比较Scala特征中的Ordered抽象类型?

发布时间:2020-12-16 18:03:20 所属栏目:安全 来源:网络整理
导读:给定下面的代码,方法foo应该比较操作符给定的参数条与lowerBound和upperBound都是相同的抽象类型Bar. trait Foo { type Bar : Ordered[Bar] val lowerBound: Bar val upperBound: Bar def foo(bar: Bar) = bar = lowerBound bar = upperBound} 这样就可以定
给定下面的代码,方法foo应该比较操作符给定的参数条与lowerBound和upperBound都是相同的抽象类型Bar.

trait Foo {
  type Bar <: Ordered[Bar]
  val lowerBound: Bar
  val upperBound: Bar
  def foo(bar: Bar) = bar >= lowerBound && bar <= upperBound
}

这样就可以定义特征Foo.问题从下面的具体类FooImpl开始.

class FooImpl extends Foo {
  type Bar = Int
  val lowerBound = 0
  val upperBound = 5
}

我知道scala.Int没有实现scala.runtime.RichInt的功能,实际上是scala.math.Ordered [Int].将类型Bar定义为RichInt则不起作用,因为它不符合scala.math.Ordered [RichInt].我第三次尝试将类型Bar定义为Ordered [Ord],其中Ord被声明为Ord类型并在FooImpl中将其定义为Int也不起作用.

一个可能接近的解决方案怎么样?

解决方法

可能有一个更优雅的解决方案,但您可以通过将类型的限制移动到方法而不是类型声明来实现此目的:

trait Foo {
  type Bar
  val lowerBound: Bar
  val upperBound: Bar
  def foo(bar: Bar)(implicit ev: Bar => Ordered[Bar]) = {
    bar >= lowerBound && bar <= upperBound
  }
}

然后你的FooImpl就像你拥有它一样:

class FooImpl extends Foo {
  type Bar = Int
  val lowerBound = 0
  val upperBound = 5
}

来自REPL:

scala> new FooImpl()
res0: FooImpl = FooImpl@2dbbec72

scala> res0.foo(3)
res1: Boolean = true

scala> res0.foo(7)
res2: Boolean = false

这里的缺点是特性可以用无序类型扩展(尽管在这种情况下不能调用foo):

class A // not Ordered

class BrokenFoo extends Foo {
  type Bar = A
  val lowerBound = new A
  val upperBound = new A
} // compiles

new BrokenFoo().foo(new A) // doesn't compile

或者,您可以将需求保持在类级别(因此阻止任何创建BrokenFoo的人),如下所示,但FooImpl必须稍微改变:

trait Foo {
  type Bar
  implicit val baz: Bar => Ordered[Bar]
  val lowerBound: Bar
  val upperBound: Bar
  def foo(bar: Bar) = { bar >= lowerBound && bar <= upperBound }
}

class FooImpl extends Foo {
  type Bar = Int
  val baz = implicitly[Bar => Ordered[Bar]]
  val lowerBound = 0
  val upperBound = 5
}

这个问题感觉像view or context bounds应该适用,但不幸的是,你似乎不能在类型声明或特征上的泛型类型参数中使用它们.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读