質問の歴史:Kotlinは最初から「デストラクチャリング」というメカニズムをサポートしており、オブジェクトやコレクション、関数から返されるデータから値を簡単に抽出できます。このメカニズムは、ScalaやJavaScript(ES6のデストラクチャリング)などの言語に触発されています。
問題:従来のOOP言語では、オブジェクトの複数のプロパティを抽出するためには、各フィールドに明示的にアクセスするか、中間構造を使用する必要があり、冗長性を生み出していました。特に、この点はループ、Mapのペアの処理、またはデータクラスでの作業において不便です。
解決策:デストラクチャリング宣言を使用すると、オブジェクトから値を一次元で変数に割り当てることができるため、コンポーネント関数(componentN)がクラスに実装されています。
コードの例:
data class Person(val name: String, val age: Int) val (n, a) = Person("Alex", 25) println("Name: $n, Age: $a") // Name: Alex, Age: 25 val map = mapOf(1 to "a", 2 to "b") for ((key, value) in map) println("$key = $value")
主な特徴:
任意のクラスをデストラクチャリングできますか?
いいえ。componentNメソッドが必要です。データクラスと標準のペア/トリプルはすでにそれらを含んでいます。通常のクラスには手動で追加できます。
例:
class Point(val x: Int, val y: Int) { operator fun component1() = x operator fun component2() = y } val (cx, cy) = Point(5, 10)
componentNが少ないオブジェクトをデストラクチャリングしようとするとどうなりますか?
変数の宣言がcomponentNの実装以上になるとコンパイラがエラーを発生させます:
data class OnlyX(val x: Int) val (x, y) = OnlyX(5) // エラー!component2がありません。
関数からの戻り値をデストラクチャリングできますか?
はい!関数はペア(Pair)、トリプル(Triple)、またはデータクラスを返すことができます。デストラクチャリングはこれをサポートしています:
fun coords() = Pair(1, 2) val (x, y) = coords()
関数にデータクラスが5つのフィールドで渡され、デストラクチャリングが5つの変数で使われる。しばらくしてフィールドが追加され、そのパターンは解析ロジック全体を見直さなければならない。無駄な変数が出現することがある。
利点:
欠点:
デストラクチャリングは、2〜3フィールドのデータクラス(例:x、y座標)のみ、または構造が保証されたmapの反復時に使用される。
利点:
欠点: