簡體   English   中英

Scala設置匹配案例

[英]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沒有定義unapplyunapplySeq方法,所以你不能用這種方式對陣它的。

這個問題有點陳舊,但我很驚訝,沒有一個答案提供了一個允許模式匹配的解決方案。

為了保留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.

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