我正在寻找scala中的东西,以更紧凑的方式编写以下代码:
def getSomething():X = {
val result = compute(...)
println(result)
result
}
我在想这样的事情:
def getSomething():X = {
MagicWrapper(compute(...)).do(println)
}
这样执行do但返回原始值。听起来像这样的事情应该存在于某个地方,但我找不到任何东西。
答案 0 :(得分:3)
使用extend-my-library模式:
implicit class SideEffectPassthrough[A](val a: A) extends AnyVal {
def se(sideEffectFunction: A => Unit): A = {
sideEffectFunction(a)
a
}
}
def compute(a: Int) = a + 2 + 3
val x = compute(1).se(println)
// x: Int = 6
编译器将为您执行包装,使语法更清晰。 (但是,请注意,当我们添加extends AnyVal
时,我们实际上确保编译器将重写此代码,以便它不会直接执行任何包装;相反,它将创建一个静态函数来处理行为,这意味着减少运行时间开销,因为不需要实例化包装器对象。)
sideEffectFunction
的{{1}}参数可以是任意函数,只要它的参数为前面表达式的结果:
se
为了完整起见,这是实现同一目标的另一种方式:
val y = compute(1).se { r =>
println("Performing a side effect now!")
println(r)
}
// y: Int = 6
参数def printAndReturn[A](block: => A): A = {
val result = block
println(result)
result
}
val x = printAndReturn(1+2+3)
// x: Int = 6
val y = printAndReturn {
val a = 1 + 2
a + 3
}
// y: Int = 6
可以是任意表达式,包括任意代码块。请注意,它是按名称传递的,因此在block
内进行评估。