7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

match-caseにおけるas-pattern(@)の嬉しさとは

Last updated at Posted at 2014-07-29

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)
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?