petitviolet blog

    Scala - パターンマッチにおけるアットマーク(@)

    2014-05-23

    QiitaScala

    参照

    http://stackoverflow.com/questions/4513380/scala-match-help

    問題

    こんなコードがある

    def flatMapSublists[A,B](ls: List[A])(f: (List[A]) => List[B]): List[B] =
      ls match {
        case Nil => Nil
        case sublist@(_ :: tail) => f(sublist) ::: flatMapSublists(tail)(f)
      }
    

    ん?sublist@(_ :: tail)???

    意味

    パターンマッチを行う際にfoo@barで、barにマッチしたものをfooにバインドするということらしい つまり、上の例ではls_ :: tailにマッチするようなものだった場合に、lssublistにバインドされる

    他の例

    参照 URLで出されている例そのままだが、リストに 3 つの要素があるかどうか確認し、 そうであった場合に、標準出力しながら、リストの 2 番目(index は 1)の要素を取得したいとき

    val something = List(1, 2, 3)
    something match {
      case ls@List(_,elem,_) => println("matching:" + ls); elem
      case _ => println("not found")
    }
    // res: AnyVal = 2
    
    // @を使わずに同様のことを行う
    something match {
      case List(a,elem,b) => println("matching:" + List(a,elem,b)); elem
      case _ => println("not found")
    }
    // res: AnyVal = 2
    
    // これでも良い
    something match {
      case List(a,elem,b) => println("matching:" + something); elem
      case _ => println("not found")
    }
    
    

    ls@なんて付けずにsomethingをそのまま使えばいいんじゃね?って思った よくわからんのでもう少し

    val list = List(1, 2, 3)
    
    list match {
      case ls@(h :: tail) => println(tail); list
      case Nil => Nil
    }
    // List(2, 3)
    // res: List[Int] = List(1, 2, 3)
    
    list match {
      case ls@(h :: tail) => println(tail); ls
      case Nil => Nil
    }
    // List(2, 3)
    // res: List[Int] with Serializable = List(1, 2, 3)
    
    

    なぜかSerializableになった この@には名前がないのかな

    from: https://qiita.com/petitviolet/items/89843d948b6fc06eba57