如何在Scala中以惯用方式处理默认值?

时间:2014-03-19 13:53:49

标签: scala

假设我有以下功能

def getHost():Option[String] = ...
def getPort():Option[Int] = ...

现在我想使用默认值,如果这些函数返回None。

def makeURL() = {
  val host = getHost() getOrElse "localhost"
  val port = getPort() getOrElse 8080
  java.net.URL("http", host, port, "myPath")
}

不幸的是,此代码在Scala中看起来不是惯用的。我希望makeURL更像是函数组合。你会如何改变makeURL

3 个答案:

答案 0 :(得分:6)

我不会改变它。没关系。这种语法的好处是简洁

当然,您可以使用纯粹的超级功能方法来改变它:

val host = getHost match {
  case Some(h) => h
  case None => "localhost"
}

但是你得到的是四行代码,而不是一行。

答案 1 :(得分:3)

我同意@serejja你所写的内容很好。但是,如果您觉得必须返回具有预设默认值的Option

 trait WithDefaults extends SomeBase{
   def defaultUrl = "localhost"

   abstract def makeURL() = withDefault(defaultUrl){ 
     super makeURL() 
   }

   protected def withDefault[A](default: A)(f: => Option[A]) = f match{
     case Some(v) => Some(v)
     case None => Some(default)
   }
 }

在其上堆叠trait,然后您的界面永远不必更改,您的所有代码都将“#34;正常工作"不知道可能存在违约的事实。然后,这也会让你问为什么它首先是Option ......

答案 2 :(得分:2)

使用getOrElse已经是惯用的,因为您推动了功能而不是拉动它:而不是问你是None吗?如果那么这样做,否则这样做'你说'我想完成这件事,如果你没有足够的信息,请使用此默认值'。
如果您愿意使用某些scalaz,那么使用|运算符看起来会更好一些:

 import scalaz._
 import Scalaz._


 def makeURL() = {
  val host = getHost() | "localhost"
  val port = getPort() | 8080
  java.net.URL("http", host, port, "myPath")
}