as-patternとはなにか
まずは例示。
val l = List("hello", "world")
l match {
case list @ List(first, _) => println(s"first element is $first : length = ${list.size}")
case _ => println("other")
}
上記の@のところ。
長さ2のリストにマッチした場合、そのインスタンスをlistという変数で後続処理で利用できるようになる。
ただしこの例では全く嬉しさが伝わらない。
そもそもlとlistが同じものを指すからでわざわざas-patternを用いて新規に変数を充てる意味が無い。
嬉しさを感じるには
これが活きるシーンとして以下を考えた。
Boxは任意の型を任意個格納できる箱。
Boxを複数持つListからBoxの要素数が2つのものを取り出しtoStringを呼ぶ、というのがやりたいこと。
この時、as-patternがあるおかげでマッチした自身のインスタンスが簡単に取得できるためやりたいことが簡潔に書ける。
case class Box[T](args: T*) {
override def toString = args.mkString(":")
}
val boxes = List(Box(), Box("A"), Box("A", "B"), Box(1, 2), Box("x", "y", "z"))
boxes.collect {
case b @ Box(_, _) => b.toString
}
collectの結果はもちろん、List("A:B", "1:2")となる。
ちなみにas-patternが無ければ(もしくは存在を知らなければ)以下の様なコードを書くことになるはずで少し冗長。
case class Box[T](args: T*) {
override def toString = args.mkString(":")
val size = args.size
}
val boxes = List(Box(), Box("A"), Box("A", "B"), Box(1, 2), Box("x", "y", "z"))
boxes.collect {
case b if b.size == 2 => b.toString
}
その他
f() match {
case success @ Success(_) => println(success)
}
とか
args match {
case Array(arg1 @ "param1") => println(arg1)