🫖
Kotlinの分解宣言を使うとJavaScriptの分割代入っぽく書けるよ
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
を扱う方がシンプルかつ実装量が少なく済んで良さそうです。
Discussion