现在我有很多可以没有的参数,我想将整个表达式赋值为默认值。
现在我正在做像
这样的事情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会很棒......)
答案 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
的领域。这特别有用,因为它适用于Option
,Validation
,Promise
,List
,Stream
等等。也就是说,就像你可以使用表达式一样:
(name |@| surname)(_ + _)
其中name
和surname
都是Option[String]
,您可以将它们切换为ValidationNEL[Exception, String]
或Promise[String]
,代码仍会执行完全相同的操作(适合使用的较高种类)。这非常强大。
答案 2 :(得分:2)
我发现了这种方式:
val fullname = (name, surname) match {
case (Some(x), Some(y)) => x + ", " + y
case _ => "unknonw"
}
但它仍然有点冗长