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

泛型 – Scala:什么是在泛型类中进行数值运算的最佳方法?

发布时间:2020-12-16 19:17:14 所属栏目:安全 来源:网络整理
导读:在 Scala中,我希望能够编写使用,/,*等运算符的泛型类,但是我没有看到如何约束T这样才能使用. 我考虑用Ordered [T]约束T,但这似乎不起作用,因为只有RichXXX(例如RichInt)扩展它,而不是Int等.我也看过Numeric [T],这只在Scala 2.8中可用吗? 这是一个具体的例
在 Scala中,我希望能够编写使用>,/,*等运算符的泛型类,但是我没有看到如何约束T这样才能使用.

我考虑用Ordered [T]约束T,但这似乎不起作用,因为只有RichXXX(例如RichInt)扩展它,而不是Int等.我也看过Numeric [T],这只在Scala 2.8中可用吗?

这是一个具体的例子:

class MaxOfList[T](list: List[T] ) {
  def max = {
    val seed: Option[T] = None

    list
      .map( t => Some(t))
      // Get the max      
      .foldLeft(seed)((i,m) => getMax(i,m) )
  }

  private def getMax(x: Option[T],y: Option[T]) = {
    if ( x.isDefined && y.isDefined )
      if ( x > y ) x else y
    else if ( x.isDefined )
      x
    else
      y
  }
}

这个类不会编译,因为有许多Ts不支持>等等

思考?

现在我使用了MixIn特性来解决这个问题:

/** Defines a trait that can get the max of two generic values
 */
trait MaxFunction[T] {
  def getMax(x:T,y:T): T
}

/** An implementation of MaxFunction for Int
 */
trait IntMaxFunction extends MaxFunction[Int] {
  def getMax(x: Int,y: Int) = x.max(y)
} 

/** An implementation of MaxFunction for Double
 */
trait DoubleMaxFunction extends MaxFunction[Double] {
  def getMax(x: Double,y: Double) = x.max(y)
}

如果我们改变原始类,可以在实例化时混合使用.

附: Mitch,受到你重写getMax的启发,这是另一个:

private def getMax(xOption: Option[T],yOption: Option[T]): Option[T] = (xOption,yOption) match {
    case (Some(x),Some(y)) => if ( x > y ) xOption else yOption
    case (Some(x),_) => xOption
    case _ => yOption
  }

解决方法

你可以使用 View Bounds.

简而言之,def foo [T<%U](t:T)是一个函数,它将采用任何或者可以隐式转换为U.因为Int可以转换为RichInt(包含你的)期望的方法),这是一个很好的使用例子.

class MaxOfList[T <% Ordered[T]](list: List[T] ) {
  def max = {
    val seed: Option[T] = None
    list.foldLeft(seed)(getMax(_,_))
  }

  private def getMax(xOption: Option[T],y: T) = (xOption,y) match {
    case (Some(x),y) if ( x > y ) => xOption
    case (_,y) => Some(y)
  }
}

PS – 我重写了你的getMax(…)方法来比较值而不是选项本身,并使用模式匹配而不是isDefined(…)

PPS – Scala 2.8将具有可能有用的数字特征. http://article.gmane.org/gmane.comp.lang.scala/16608

附录

只是为了咯咯笑,这里的超紧凑版本完全消除了getMax方法:

class MaxOfList[T <% Ordered[T]](list: List[T] ) {
  def max = list.foldLeft(None: Option[T]) {
      case (Some(x),y) if ( x > y ) => Some(x)
      case (_,y) => Some(y)
  }
}

然而另一个附录

这个版本对大型列表更有效…避免为每个元素创建Some(x):

class MaxOfList[T <% Ordered[T]](list: List[T] ) {
  def max = {
    if (list.isEmpty) None
    else Some(list.reduceLeft((a,b) => if (a > b) a else b))
  }
}

最后一个,我保证!

此时,您可以放弃该类并使用一个函数:

def max[T <% Ordered[T]](i: Iterable[T]) = {
    if (i.isEmpty) None
    else Some(i.reduceLeft((a,b) => if (a > b) a else b))
  }

(编辑:李大同)

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

    推荐文章
      热点阅读