【问题标题】:Scala: how to handle many params that can be NoneScala:如何处理许多可以为 None 的参数
【发布时间】:2012-06-08 03:31:51
【问题描述】:

现在我有很多可以为空的参数,我想为整个表达式分配一个默认值。

现在我正在做类似的事情

var name: Option[String] = None
var surname: Option[String] = Some("Smith")

val fullName:String = {
  name.map { name => 
    surname.map { surname => 
      surname + ", " + name
    }.getOrElse("unknown")
  }.getOrElse("unknown")
}

但它有点过于冗长。我想知道什么是更惯用和更优雅的方式来处理它,理想情况下它会是这样的(当然是伪代码!):

val fullName = (name + ", " + surname).getOrElse("unknown")

或类似的东西......

(只是避免双重 .getOrElse 会很棒......)

【问题讨论】:

    标签: scala option optional-parameters


    【解决方案1】:

    这个怎么样

    scala> val fullName = (for(n <-name;s <-surname) yield n + s).getOrElse("unknown")  
    fullName: String = unknown
    

    【讨论】:

    • 脱糖:surname flatMap (x =&gt; name map (x + ", " + _)) getOrElse "unknown"
    【解决方案2】:

    您可能想了解一点应用函子,因为可以以各种方式使用相同的模式。使用scalaz,有applicative builder:

    (name |@| surname)(_ + _)
    

    这是怎么回事:

    (M[A] |@| M[B])(fabc) ~> M[C] //fabc is a function f: (A, B) => C
    

    也就是说,函数f 被提升到应用函子M 的领域。这特别有用,因为它适用于OptionValidationPromiseListStream 等等。也就是说,就像您可能使用的表达式一样:

    (name |@| surname)(_ + _)
    

    如果namesurname 都是Option[String],您可以将它们切换为ValidationNEL[Exception, String]Promise[String],并且代码仍然会执行完全相同的操作(适用于正在使用的更高类型)。这非常强大。

    【讨论】:

    【解决方案3】:

    我是这样找到的:

    val fullname = (name, surname) match {
      case (Some(x), Some(y)) => x + ", " + y
      case _ => "unknonw"
    }
    

    但还是有点啰嗦

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      • 2018-06-14
      • 2010-11-03
      • 2018-07-08
      • 1970-01-01
      相关资源
      最近更新 更多