【问题标题】:Scala empty default closure?Scala空默认关闭?
【发布时间】:2011-05-22 04:46:42
【问题描述】:

只是一个简单的问题,我似乎无法找到答案。

我在 Scala 中有一个方法定义,如下所示:

def execute(goals: List[String],
            profiles: List[String] = List(),
            loggingCallback: (String) => Unit = { _ => }): Result = {
    // method body
    loggingCallback("a message")
}

我想知道是否有更好的方法来指定默认的空闭包。问题不在于如何实现日志记录,这只是一个示例。

【问题讨论】:

  • 你的做法有什么问题?很简洁!
  • 我并不是说我指定它的方式有问题。我只是不知道这个规范是否足够和/或良好的风格。

标签: scala closures default-value


【解决方案1】:

() 的值是 unit 的一个实例,所以这应该可以解决问题:

def execute(
  goals: List[String],
  profiles: List[String] = Nil,
  loggingCallback: (String) => Unit = { _ => () }): Result =
{
  // method body
  loggingCallback("a message")
  // do something returning a Result
}

更新

如果某些内容是可选的,那么明确说明通常更有意义,这也会产生更好的自文档化代码:

def execute(
  goals: List[String],
  profiles: List[String] = Nil,
  loggingCallback: Option[(String) => Unit] = None): Result =
{
  // method body
  loggingCallback forEach { _.apply("a message") }
  // do something returning a Result
}

更新 2

像这样的 DSL 式的情况也是极少数我会容忍在 Scala 中使用 null 的情况之一:

def execute(
  goals: List[String],
  profiles: List[String] = Nil,
  loggingCallback: (String) => Unit = null
): Result = {
  // method body
  val log = Option(loggingCallback) getOrElse {_ => ()}
  log("a message")
  // do something returning a Result
}

注意 Option(loggingCallback)立即 将可空的 loggingCallback 转换为良好的类型安全 Option,然后 getOrElse 提供备用替代方案。

【讨论】:

  • 你是对的,在这里使用 Option 可以让调用者更清楚。
【解决方案2】:

您的解决方案很好。您可以为Function1[X, Unit] 引入类型别名;根据凯文的回答使用(),并删除不必要的括号。

scala> type Effect[-A] = (A => Unit)
defined type alias Effect

scala> def foo(f: Effect[String] = _ => ()) = ()
foo: (f: (String) => Unit)Unit

您还可以定义一个noop 函数:

scala> val noop = (a: Any) => ()
noop: (Any) => Unit = <function1>

scala> def foo(f: Effect[String] = noop) = ()

【讨论】:

    猜你喜欢
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多