我经常有这样的功能:
{
val x = foo;
bar(x);
x
}
例如,bar
通常类似于Log.debug
。
是否有更简洁,惯用的方式来运行它?例如,内置函数,如
def act[A](value: A, f: A => Any): A = { f(value); value }
这样我就可以只写act(foo, bar _)
。
答案 0 :(得分:1)
我不确定我是否正确理解了这个问题,但是如果我这样做了,那么我经常使用这个从Spray工具包中获取的方法:
def make[A, B](obj: A)(f: A => B): A = { f(obj); obj }
然后你可以写下以下内容:
utils.make(new JobDataMap()) { map =>
map.put("phone", m.phone)
map.put("medicine", m.medicine.name)
map.put("code", utils.genCode)
}
答案 1 :(得分:1)
使用您编写的act
函数对我来说似乎是完全惯用的。我不知道有一种内置的方法可以做到这一点,但我只是把这种东西扔进公共场所"或" utils"我到处使用的项目。
如果bar函数通常是相同的(例如Log.debug),那么你也可以为它创建一个特定的包装函数。例如:
def withDebug[A](prefix: String)(value: A)(implicit logger: Logger): A = {
logger.debug(prefix + value)
value
}
然后您可以按如下方式使用:
implicit val loggerI = logger
def actExample() {
// original method
val c = act(2 + 2, logger.debug)
// a little cleaner?
val d = withDebug("The sum is: ") {
2 + 2
}
}
或者更多的语法糖:
object Tap {
implicit def toTap[A](value: A): Tap[A] = new Tap(value)
}
class Tap[A](value: A) {
def tap(f: A => Any): A = {
f(value)
value
}
def report(prefix: String)(implicit logger: Logger): A = {
logger.debug(prefix + value)
value
}
}
object TapExample extends Logging {
import Tap._
implicit val loggerI = logger
val c = 2 + 2 tap { x => logger.debug("The sum is: " + x) }
val d = 2 + 2 report "The sum is: "
assert(d == 4)
}
tap
采用任意函数,而report
只包装记录器。当然,您可以将您喜欢的其他常用点击添加到Tap
类。
答案 2 :(得分:0)
请注意,Scala已经包含语法重量级版本:
foo match { case x => bar(x); x }
但是在Ruby中创建较短的版本(tap
- 我建议使用相同的名称)可以有优势。