【问题标题】:Avoiding the variable in "val x = foo; bar(x); x" [duplicate]避免“val x = foo; bar(x); x”中的变量 [重复]
【发布时间】:2013-07-08 10:49:48
【问题描述】:

我经常有这样的功能:

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

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

有没有更短的、惯用的方式来运行它?例如,像

这样的内置函数
def act[A](value: A, f: A => Any): A = { f(value); value }

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

【问题讨论】:

  • 这就是副作用对人们的影响 =)

标签: scala variables idioms


【解决方案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)
}

【讨论】:

    【解决方案2】:

    使用你写的act 函数对我来说似乎非常地道。我不知道有什么内置的方法可以做到这一点,但我会把这种东西放在我到处使用的“commons”或“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 类中添加您喜欢的任何其他常用水龙头。

    【讨论】:

    【解决方案3】:

    请注意,Scala 已经包含一个语法重量级的版本:

    foo match { case x => bar(x); x }
    

    但创建较短的版本(Ruby 中的tap——我建议使用相同的名称)可能会有优势。

    【讨论】:

    • 这似乎比原来的{ val x = foo; bar(x); x }更长。
    • @PetrPudlák - 确实如此,这就是为什么在大多数情况下首选原件的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    相关资源
    最近更新 更多