📦 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.
💡 Cú pháp cơ bản
Phần tiêu đề “💡 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
Phần tiêu đề “🏗️ 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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “🔄 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 (_)
Phần tiêu đề “🚫 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
Phần tiêu đề “λ 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.Entrymap.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
Phần tiêu đề “📦 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
Phần tiêu đề “🛠️ 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
Phần tiêu đề “✅ 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