Bỏ qua để đến nội dung

📦 Destructuring Declarations

🎯 Mục tiêu: Hiểu cách phân rã (destructure) một object thành nhiều biến riêng lẻ, sử dụng componentN() functions và áp dụng trong loops, lambdas.


Destructuring cho phép bạn khai báo và khởi tạo nhiều biến cùng lúc từ một object:

val (name, age) = person

Dòng code trên tương đương với:

val name = person.component1()
val age = person.component2()

Để một object có thể được destructure, nó phải có các hàm componentN() (với N là 1, 2, 3…) được đánh dấu bằng từ khóa operator.

Data classes tự động generate componentN() cho các property trong primary constructor theo thứ tự khai báo.

data class User(val name: String, val age: Int)
fun main() {
val user = User("Alice", 25)
val (n, a) = user // n=Alice, a=25
}

Bạn có thể tự định nghĩa componentN() cho class thường:

class Point(val x: Int, val y: Int) {
operator fun component1() = x
operator fun component2() = y
}

Destructuring cực kỳ hữu ích khi duyệt qua Map hoặc List các object:

val map = mapOf("Alice" to 25, "Bob" to 30)
for ((name, age) in map) {
println("$name is $age years old")
}

Nếu bạn không cần dùng một thành phần nào đó, hãy dùng _ để bỏ qua, giúp code gọn hơn và tránh warning unused variable:

val (_, status) = getResult()

Hàm componentN() tương ứng sẽ không được gọi.


Bạn có thể destructure tham số của lambda expression:

map.mapValues { (key, value) -> "$value!" }

Cú pháp:

  • (a, b): Destructure tham số đầu tiên.
  • (a, b), c: Destructure tham số đầu, giữ nguyên tham số thứ 2.
// Ví dụ với Map.Entry
map.forEach { (k, v) ->
println("$k -> $v")
}

Nếu không dùng 1 biến:

map.forEach { (_, v) -> println(v) }

Chỉ định kiểu dữ liệu nếu cần:

map.mapValues { (_, value): Map.Entry<Int, String> -> "$value" }

Thay vì dùng Pair hoặc Triple chung chung, hãy định nghĩa Data Class để trả về nhiều giá trị có tên rõ ràng:

data class Result(val result: Int, val status: String)
fun calculate(): Result {
return Result(100, "Success")
}
fun main() {
val (res, stat) = calculate()
}

Bài tập 1: Destructure Custom Class

// TODO: Tạo class Vector3 (x, y, z) hỗ trợ destructuring

Lời giải:

class Vector3(val x: Int, val y: Int, val z: Int) {
operator fun component1() = x
operator fun component2() = y
operator fun component3() = z
}
fun main() {
val v = Vector3(1, 2, 3)
val (x, y, z) = v
println("Vector: $x, $y, $z")
}

  • Hiểu cơ chế componentN()
  • Sử dụng destructuring với Data Class và Map
  • Dùng _ để bỏ qua biến không dùng
  • Áp dụng destructuring trong Lambda parameters