This Expressions trong Kotlin
🎯 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
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)
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
- 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
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)
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
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
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
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
- 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)
Last updated on