簡體   English   中英

Scala:帶有案例類和代碼塊的模式匹配Option

[英]Scala: pattern matching Option with case classes and code blocks

我開始學習出色的Scala語言,並且對“深度”模式匹配有疑問

我有一個簡單的Request類:

case class Request(method: String, path: String, version: String) {}

還有一個函數,該函數嘗試匹配request實例並構建相應的響應:

def guessResponse(requestOrNone: Option[Request]): Response = {
    requestOrNone match {
        case Some(Request("GET", path, _)) => Response.streamFromPath(path)
        case Some(Request(_, _, _)) => new Response(405, "Method Not Allowed", requestOrNone.get)
        case None => new Response(400, "Bad Request")
    }
}

看,我在case語句中使用requestOrNone.get來獲取操作Request對象。 由於case語句匹配,類型安全嗎? 我覺得有點難看。 是否可以從Some “解包” Request對象,但仍然能夠匹配Request類字段?

如果我想在帶有局部變量等的case進行復雜的計算該怎么辦?我可以在case語句后使用{}塊嗎? 我將IntelliJ Idea與官方Scala插件一起使用,並且突出顯示了括號,建議將其刪除。

如果可能的話,將火柴放在火柴中是一種好習慣嗎?

... match {
  case Some(Request("GET", path, _)) => {
      var stream = this.getStream(path)

      stream match {
        case Some(InputStream) => Response.stream(stream.get)
        case None => new Response(404, "Not Found)
      }
  }
}

對於問題的第一部分,可以使用@命名匹配的值:

scala> case class A(i: Int)
defined class A

scala> Option(A(1)) match {
     |   case None => A(0)
     |   case Some(a @ A(_)) => a
     | }
res0: A = A(1)

Scala規范8.1.3:模式綁定器 ):

模式綁定器x @ p由模式變量x和模式p組成。 變量x的類型是模式p的靜態類型T。 如果v的運行時類型也是T的實例,則此模式匹配與模式p匹配的任何值v,並且它將變量名綁定到該值。

但是,您無需在示例中進行操作:由於您沒有與Request任何內容匹配,而只是與Request ,因此您可以:

case Some(req) => new Response(405, "Method Not Allowed", req)

對於第二部分,您可以嵌套match es。 Intellij建議刪除括號的原因是它們是不必要的:關鍵字case足以知道前面的case已完成。

至於是否是一個好習慣,這顯然取決於情況,但是我可能會嘗試將代碼重構為較小的塊。

您可以按以下方式重寫模式(使用別名)。

case Some(req @ Request(_, _, _)) => new Response(405, "Method Not Allowed", req)

您不能在模式中使用代碼塊,而只能使用警惕( if ... )。

有模式匹配的編譯器插件,例如豐富的模式匹配

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM