🏷️ This Expressions
🎯 Mục tiêu: Hiểu cách sử dụng từ khóa
thisđể tham chiếu đến đối tượng hiện tại, đặc biệt trong các ngữ cảnh lồng nhau (nested scopes) và extension functions.
💡 Cơ bản về this
Phần tiêu đề “💡 Cơ bản về this”this tham chiếu đến receiver (đối tượng nhận) hiện tại:
- Trong method của class:
thislà đối tượng gọi method đó. - Trong extension function:
thislà đối tượng được mở rộng (receiver).
class Person(val name: String) { fun printName() { println("My name is ${this.name}") // this tham chiếu đến instance Person }}🏷️ Qualified this (Tham chiếu this có định danh)
Phần tiêu đề “🏷️ Qualified this (Tham chiếu this có định danh)”Khi làm việc với các scope lồng nhau (inner class, anonymous object, lambda with receiver), bạn cần dùng label để chỉ định this nào bạn muốn truy cập.
Cú pháp: this@label
Các quy tắc Label
Phần tiêu đề “Các quy tắc Label”- Classes: Tên class là label ẩn.
- Extensions: Tên function là label ẩn.
- Lambda with receiver: Có thể đặt label thủ công hoặc dùng tên function nhận lambda.
Ví dụ minh họa
Phần tiêu đề “Ví dụ minh họa”class A { // label ẩn @A inner class B { // label ẩn @B fun Int.foo() { // label ẩn @foo, receiver là Int val a = this@A // this của class A val b = this@B // this của class B
val c = this // this của foo() (Int) val c1 = this@foo // tđ
val funLit = lambda@ fun String.() { val d = this // this của funLit (String) val d1 = this@lambda } } }}🔽 Implicit this (this ẩn)
Phần tiêu đề “🔽 Implicit this (this ẩn)”Khi gọi member function hoặc property trên this, bạn có thể bỏ qua this.:
class User { val name = "Alice"
fun printInfo() { println(name) // Tương đương this.name println(this.name) }}Lưu ý quan trọng
Phần tiêu đề “Lưu ý quan trọng”Nếu có một hàm cục bộ (local function) hoặc biến trùng tên với member, bạn phải dùng this để phân biệt:
class A { fun printLine() { println("Member function") }
fun invokePrintLine() { fun printLine() { println("Local function") } // Trùng tên
printLine() // Gọi local function this.printLine() // Gọi member function }}🏗️ Type-safe Builders & Lambda with Receiver
Phần tiêu đề “🏗️ Type-safe Builders & Lambda with Receiver”this expression rất quan trọng trong Type-safe builders (như HTML DSL hoặc Gradle kts).
class HTML { fun body() { /*...*/ }}
fun html(init: HTML.() -> Unit): HTML { val html = HTML() html.init() // html là receiver, nên trong init(), this == html return html}
fun main() { html { // this là đối tượng HTML this.body() body() // Có thể bỏ this }}🛠️ Thực hành
Phần tiêu đề “🛠️ Thực hành”Bài tập 1: Xác định this
class Outer { val id = "Outer"
inner class Inner { val id = "Inner"
fun run() { // TODO: In ra "Outer" và "Inner" dùng `this` } }}Lời giải:
fun run() { println(this.id) // Inner println(this@Outer.id) // Outer}✅ Checklist
Phần tiêu đề “✅ Checklist”- Hiểu
thiscơ bản trong class và extension - Sử dụng
this@Labelđể truy cập outer scope - Phân biệt implicit
thisvà local variables - Hiểu vai trò của
thistrong Lambda with Receiver (DSLs)