如何避免一直在Scala中编写代码?

时间:2018-06-29 14:36:40

标签: scala

我经常发现自己写这篇文章,但我不喜欢它。替代品?

val b = {
  val a = getA()
  println(a)
  a
}

我讨厌分配一个正义的东西来使用它(不一定与println一起使用,但是我不关心结果的任何功能)

3 个答案:

答案 0 :(得分:3)

也许是这样?

implicit class DebugTrace[A](value: A) {
  def trace[U](sideEffectyFunction: A => U): A = {
    sideEffectyFunction(value)
    value 
  }
}

如果这在范围内,您将在所有方法上获得方法trace。此方法对值运行参数函数,然后返回值。

例如,

42 trace println

打印42并产生42


它也可以用于更复杂的块(示例REPL交互):

scala> 42 trace { a =>
     |   println(s"The value of the constant 42 is = $a")
     |   println(s"And the square is = ${a * a}")
     | }
The value of the constant 42 is = 42
And the square is = 1764
res4: Int = 42

类似地:

def getA(): Int = 42
val b = getA() trace println

打印getA()的输出并将b设置为42

一个更好的问题是:到底为什么您要污染任何具有println副作用的计算?查看println并不是确保代码正确运行的方式(即使我承认可视化某些复杂的相互递归算法也可能会有所帮助)。

答案 1 :(得分:2)

怎么样:

def callReturn[A](value: A, f: A => Unit): A = {
    f(value)
    value
}

val b = callReturn(getA(), println)

然后您可以定义跟踪,例如:

def trace[A](value: A): A = callReturn(value, println)

val b = trace(getA())

答案 2 :(得分:2)

这正是Scala 2.13的新tap链接操作的用例之一:

import util.chaining._

// def getA() = 43
val b = getA().tap(println)
// 43
// b: Int = 43

在返回时,tap链接操作对值(在这种情况下是println返回的值:getA())上施加了副作用(在这种情况下为43)此值未修改:

  

def tap [U](f:(A)=> U):A