Tour of Scala

抽出子オブジェクト

Language
Info: JavaScript is currently disabled, code tabs will still work, but preferences will not be remembered.

抽出子オブジェクトはunapplyメソッドを持つオブジェクトです。 applyメソッドが引数を取り、オブジェクトを作るコンストラクタであるように、unapplyは1つのオブジェクトを受け取り、引数を返そうとします。 これはパターンマッチングと部分関数で最も頻繁に使われます。

import scala.util.Random
object CustomerID {
 def apply(name: String) = s"$name--${Random.nextLong()}"
 def unapply(customerID: String): Option[String] = {
 val stringArray: Array[String] = customerID.split("--")
 if (stringArray.tail.nonEmpty) Some(stringArray.head) else None
 }
}
val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908
customer1ID match {
 case CustomerID(name) => println(name) // prints Sukyoung
 case _ => println("Could not extract a CustomerID")
}

applyメソッドはnameからCustomerID文字列を作ります。unapplyは逆にnameを返します。 CustomerID("Sukyoung")は、CustomerID.apply("Sukyoung")を短く書く構文です。 case CustomerID(name) => println(name)では、unapplyメソッドを呼んでいます。

値を定義する文で、パターン中に新しい変数を使うことができるので、抽出子は変数を初期化するのに使えます。この場合unapplyメソッドが初期値を与えます。

val customer2ID = CustomerID("Nico")
val CustomerID(name) = customer2ID
println(name) // prints Nico

これは val name = CustomerID.unapply(customer2ID).getと同じです。

val CustomerID(name2) = "--asdfasdfasdf"

もし一致しない場合scala.MatchErrorが投げられます。

val CustomerID(name3) = "-asdfasdfasdf"

unapplyの戻り値型は以下のように選ばれなければなりません。

  • ただのテストであれば、Booleanを返します。例えばcase even()
  • T型のサブバリュー1つを返すのであれば、Option[T]を返します。
  • いくつかのサブバリューT1,...,Tnを返したいのであれば、オプショナルタプルOption[(T1,...,Tn)]でグループ化します。

時々、抽出する値の数が確定せず、入力に応じて任意の数の値を返したいことがあります。 この場合は、Option[Seq[T]]を返すunapplySeqメソッドを持つ抽出子を定義することができます。 これらのパターンと同様の例として以下のものがあります。 case List(x, y, z) =>を使ってListを分解する例やcase r(name, remainingFields @ _*) =>.のように正規表現Regexを使ってStringを分解する例です。

Contributors to this page:

Contents

AltStyle によって変換されたページ (->オリジナル) /