概要
Scalaを触るとよく聞くapplyとunapply。特に意識せずともクラスに「case class」を付ければ動くコードを書けてしまうのですが、出来れば理解したいと思いメモを書きます。
applyとunapplyについて
applyはオブジェクト構築時に呼ばれるメソッドです(オブジェクト構築時にapplyを書くのが省略されるケースが多いです)。unapplyはパターンマッチで引数を取得するメソッドです、オブジェクトのmatch式を書くときに自動で呼ばれます。呼び出し方のイメージは@yotsak83さんのScalaの抽出子(apply, unapply)サンプルと呼ばれるタイミングが分かりやすいです。
case classについて
クラスの定義の頭に「case class」を付けると、@lrf141さんのjava経験者のScala入門メモ [ケースクラス、オブジェクト]の記事の通り、apply・unapplyに加えcopyなどのメソッドを自動で生成してくれます。クラスを定義するときはcase classを使用することが多いですが、その意義についてScala で case class と apply() と unapply() の関係がよくわかってなかったので調べたら関数リテラルについても学びがあった話の記事が参考になります。
サンプルコード
2つの文字列の引数があるコンストラクタを持つクラスで、引数を2つ文字列結合して出力をする場合を例に、サンプルコードを書いてみます。
case classを使わない場合と使う場合で分けています。
case classを使わない場合
【クラス定義】
// 引数を取得するためコンストラクタにvalを設定する。
class NonApplyTest(val test1input:String , val test2input:String){
}
【呼び出し】
// オブジェクトをnewする。
var nonApplyTest = new NonApplyTest("test1" , "test2")
// 引数の変数名から直接値を取得する。
println(nonApplyTest.test1input + nonApplyTest.test2input)
case classを使う場合
【クラス定義】
// unapplyがあるのでコンストラクタにvalは不要。
case class ApplyTestWithCase(test1input:String , test2input:String){
}
【呼び出し】
// ここでapplyが呼ばれる。
val applyTestWithCase = ApplyTestWithCase("test1" , "test2")
applyTestWithCase match{
// ここでunapplyが呼ばれる
case ApplyTestWithCase(s1 , s2) => println(s1 + s2)
case _ => println("None")
}