避免变量在" val x = foo;杆(X); X"

时间:2013-07-10 13:23:41

标签: scala variables idiomatic

我经常有这样的功能:

{
  val x = foo;
  bar(x);
  x
}

例如,bar通常类似于Log.debug

是否有更简洁,惯用的方式来运行它?例如,内置函数,如

def act[A](value: A, f: A => Any): A = { f(value); value }

这样我就可以只写act(foo, bar _)

3 个答案:

答案 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 - 我建议使用相同的名称)可以有优势。