Scala:如何处理许多可以是None的参数

时间:2012-06-03 23:46:52

标签: scala option optional-parameters

现在我有很多可以没有的参数,我想将整个表达式赋值为默认值。

现在我正在做像

这样的事情
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会很棒......)

3 个答案:

答案 0 :(得分:15)

这个怎么样

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

答案 1 :(得分:13)

您可能想要了解一下 applicative functors ,因为可以通过各种方式使用相同的模式。使用scalaz,有一个应用程序构建器:

(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],代码仍会执行完全相同的操作(适合使用的较高种类)。这非常强大。

答案 2 :(得分:2)

我发现了这种方式:

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

但它仍然有点冗长