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

什么是在Scala中重用函数结果的好方法

发布时间:2020-12-16 10:08:33 所属栏目:安全 来源:网络整理
导读:让我通过例子澄清我的问题.这是在 Scala中使用尾递归编写的标准取幂算法: def power(x: Double,y: Int): Double = { def sqr(z: Double): Double = z * z def loop(xx: Double,yy: Int): Double = if (yy == 0) xx else if (yy % 2 == 0) sqr(loop(xx,yy /
让我通过例子澄清我的问题.这是在 Scala中使用尾递归编写的标准取幂算法:

def power(x: Double,y: Int): Double = {
  def sqr(z: Double): Double = z * z
  def loop(xx: Double,yy: Int): Double = 
    if (yy == 0) xx
    else if (yy % 2 == 0) sqr(loop(xx,yy / 2))
    else loop(xx * x,yy - 1)

  loop(1.0,y)
}

这里sqr方法用于产生循环结果的平方.看起来不是一个好主意 – 为这样一个简单的操作定义一个特殊的功能.但是,我们不能只写loop(..)* loop(..),因为它会使计算加倍.

我们也可以用val编写它而没有sqr函数:

def power(x: Double,y: Int): Double = {
  def loop(xx: Double,yy: Int): Double = 
    if (yy == 0) xx
    else if (yy % 2 == 0) { val s = loop(xx,yy / 2); s * s }
    else loop(xx * x,y)
}

我不能说它看起来比使用sqr更好,因为它使用状态变量.第一种情况更具功能性第二种方式更适合Scala.

无论如何,我的问题是当你需要后处理函数的结果时如何处理案例?也许Scala有其他方法可以实现这一目标?

解决方法

你可以使用“前进管道”.我从这里得到了这个想法: Cache an intermediate variable in an one-liner.

所以

val s = loop(xx,yy / 2); s * s

可以改写成

loop(xx,yy / 2) |> (s => s * s)

使用像这样的隐式转换

implicit class PipedObject[A](value: A) {
  def |>[B](f: A => B): B = f(value)
}

正如彼得指出的那样:使用隐式值类

object PipedObjectContainer {
  implicit class PipedObject[A](val value: A) extends AnyVal {
    def |>[B](f: A => B): B = f(value)
  }
}

像这样使用

import PipedObjectContainer._
loop(xx,yy / 2) |> (s => s * s)

更好,因为它不需要临时实例(需要Scala> = 2.10).

(编辑:李大同)

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

    推荐文章
      热点阅读