[英]Scala Set match case
我正在學習scala,作為最好的培訓,我正在將舊的Java算法轉換為函數式編程風格。 我有以下代碼:
def test(originalSet: Set[Int]):Boolean = originalSet match {
case Set() => true
case x::y => false
}
此代碼適用於列表,但對於集合,它給出了以下編譯錯誤:
- value Set is not a case class constructor, nor does it have an unapply/unapplySeq
method
和
- constructor cannot be instantiated to expected type; found : scala.collection.immutable.::[B] required:
scala.collection.immutable.Set[Int]
- constructor cannot be instantiated to expected type; found : scala.collection.immutable.::[B] required:
scala.collection.immutable.Set[Int]
問題是什么? 如何測試Set為空的情況? 如果設置有頭尾的話,我怎么能這樣呢?
Set
定義了一個isEmpty
方法,因此最簡單的解決方案是
def test(originalSet: Set[Int]): Boolean = originalSet.isEmpty
使用時與List匹配時
list match {
case Nil => true
case x :: y => false
}
你匹配List Nil
對象和::
class,它相當於
list match {
case Nil => true
case ::(x, y) => false
}
所以你不能在Set
使用這個表單。
使用以下方法對List進行模式匹配時:
list match {
case List(a, b) => true
case _ => false
}
您正在使用列表提取器。 List
提取器是使用unapplySeq
定義的,如果列表是給定格式,則匹配。 Set
沒有定義unapply
或unapplySeq
方法,所以你不能用這種方式對陣它的。
這個問題有點陳舊,但我很驚訝,沒有一個答案提供了一個允許模式匹配的解決方案。
為了保留Set
語義並能夠進行模式匹配,您需要實現一個自定義unapply
方法,該方法接受Set
for input。 這是一個非常有用的模式,可以應用於任何類型。
object EmptySet {
def unapply[A](s: Set[A]): Boolean = s.isEmtpy
}
object NonEmptySet {
def unapply[A](s: Set[A]): Option[Set[A]] =
if (s.isEmpty) None
else Some(s)
}
def foo(bars: Set[Int]): String = bars match {
case EmptySet => "No Bars"
case NonEmptySet(values) => s"Bars: $values"
}
這里描述的模式: http : //docs.scala-lang.org/tutorials/tour/extractor-objects.html
Set沒有unapply方法,也沒有Seq,因此在它們上使用case解構器沒有多大意義。 (參考Scala模式與集合匹配 )..但我會添加自己的注釋,我一直在學習scala並且最初認為案例匹配應該用於所有事情 - 但在函數式編程中使用if- then語句是完全可以接受的,並且在這里最有意義。
def test(originalSet: Set[Int]):Boolean = ! originalSet.isEmpty
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.