Destructuring Declarations (Phân rã biến) trong Kotlin
🎯 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.
💡 Cú pháp cơ bản
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) = personDòng code trên tương đương với:
val name = person.component1()
val age = person.component2()🏗️ componentN Functions
Để 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
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
}Regular Classes
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
}🔄 Sử dụng trong Loops
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")
}🚫 Bỏ qua biến với Underscore (_)
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.
λ Destructuring trong Lambdas
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" }📦 Trả về nhiều giá trị từ hàm
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()
}🛠️ Thực hành
Bài tập 1: Destructure Custom Class
// TODO: Tạo class Vector3 (x, y, z) hỗ trợ destructuringLờ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")
}✅ Checklist
- 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