假设我有以下功能
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
?
答案 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")
}