首页 文章

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

提问于
浏览
3

假设我有以下功能

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 回答

  • 6

    我不会_1281234很好 . 这种语法的好处是它是 concise .

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

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

    但是你会得到四行代码而不是一行代码 .

  • 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 ,然后你的界面永远不必改变,你的所有代码都会忘记可能存在默认值的事实 . 然后,这也会让你问为什么它首先是 Option ...

  • 2

    使用 getOrElse 已经是惯用的了,因为你're pushing functionality instead of pulling it : instead of asking '你是 None ?如果那么这样做就行了' you'重新说'I want this done and if you don' t有足够的信息使用这个默认值' .
    如果你愿意使用 scalaz ,那么使用 | 运算符看起来会更好一些:

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

相关问题