JavaScriptの分割代入とは?
誰しも書いたことがあるであろうこれのこと。
const obj = {a:0, b:1};
const { a, b } = obj;
// これは以下のものと同様
// const a = obj.a;
// const b = obj.b;
Kotlinの分割宣言とは?
以下のようなコードのこと。operator fun componentN()
のように記述する。
class Data(val firstName: String, val lastName: String, val age: Int, val sex: Int){
operator fun component1() = firstName
operator fun component2() = lastName
operator fun component3() = age
operator fun component4() = sex
}
結果、このように分割代入することができる。
fun main() {
val data = Data("hoge", "fuga", 20, 1)
val (firstname) = data
println(firstname) // hoge
}
Pair...??
この分割代入の記法を見た時、「Pair...?」や「Triple...?」と思われた方もいらっしゃるでしょう。
ではPair
はoperator fun componentN()
のように書かれているのか?
実装を見てみると…
public data class Pair<out A, out B>(
public val first: A,
public val second: B
) : Serializable {
/**
* Returns string representation of the [Pair] including its [first] and [second] values.
*/
public override fun toString(): String = "($first, $second)"
}
そんなことはなく、単にdata class
として宣言されている。これはどういうことか?
data classを用いた分割宣言
そう、実はdata class
の内部ではoperator fun componentN()
は自動で生成されるようになっている。
つまり、以下のコードと先ほどのclass Data
は同じように使うことができる。
data class Data(val firstName: String, val lastName: String, val age: Int, val sex: Int)
fun main() {
val data = Data("hoge", "fuga", 20, 1)
val (firstname) = data
println(firstname)
}
おわり
ではどう使い分けるのがいいだろうか?という話だが、これはclass
とdata class
の性質によるかと思う。
class
でデータを持ちつつも、そのデータを加工して保持するproccessor
的なsetter
が必要な場合は、operator fun componentN()
として持ってあげると良いかもしれない。
逆にDTOのように、単に値を持ち回したいだけ という場面では普通にdata class
を扱う方がシンプルかつ実装量が少なく済んで良さそう。