簡體   English   中英

Scala中的案例類,模式匹配和curried構造函數

[英]Case classes, pattern matching and curried constructors in Scala

他們似乎沒有很好地混合:

abstract class A
case class B (var a: Int)(var b: String) extends A
case class C extends A

以下內容不起作用:

B(1)("1") match {
  case B(a)(b) => print("B")
  case C() => print("C")
}

問題是模式匹配和curried參數似乎不起作用。 有解決辦法嗎?

如果你看一下為B類創建的unapply函數的簽名,你會看到它是: unapply(x$0: Q): Option[Int] 因此,unapply函數與case類的第一個參數范圍一起使用。

scala規范(§5.3.2)證實了這一點:

案例類的第一個參數部分中的形式參數稱為元素; 他們受到特殊待遇。 首先,可以將這樣的參數的值提取為構造函數模式的字段。

它明確聲稱只有第一個參數部分可通過提取器獲得。

幾個解決方法:

  • 發現你的參數
  • 如果要測試2個值,請使用與guard匹配的模式: case x@B(3) if xb == "bazinga" => ...
  • 使用普通類並使用您自己的apply / unapply定義您自己的伴隨對象

這有什么問題?

def m(a: A) = a match {
  case b: B => print("B")
  case c: C => print("C")
}

我只是問,因為你沒有要求比這更多的功能。

編輯

這有助於:

object Dog {
   def apply(name: String)(size: Int) = new Dog(name)(size)
   def unapply(dog: Dog) = Some(dog.name, dog.size)
}
class Dog(val name: String)(var size: Int)

現在你可以像這樣創建狗:

new Dog("Snoopy")(10) 

或者像這樣:

Dog("Snoopy")(10)

但是當你在狗上進行模式匹配時,構造函數模式就不會被咖喱了。

Dog("Snoopy")(10) match {
   case Dog(a, b) => // do sth with a or b
}

您可以使用普通的case類,只需定義一個帶有多個參數列表的工廠方法。

暫無
暫無

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

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