From 96b9baed2f5ddd1a8c517ae823b454d09cb3a856 Mon Sep 17 00:00:00 2001 From: "aleksandra.epanchintseva" Date: Mon, 6 Jul 2026 14:35:22 +0200 Subject: [PATCH 1/3] this expressions: initial commit --- docs/topics/this-expressions.md | 221 ++++++++++++++++++++++++++++---- 1 file changed, 198 insertions(+), 23 deletions(-) diff --git a/docs/topics/this-expressions.md b/docs/topics/this-expressions.md index a714255fb55..51006713ea5 100644 --- a/docs/topics/this-expressions.md +++ b/docs/topics/this-expressions.md @@ -1,42 +1,217 @@ [//]: # (title: This expressions) -To denote the current _receiver_, you use `this` expressions: +The `this` expression refers to the current object or receiver. + +How you use `this` depends on the context: * In a member of a [class](classes.md#inheritance), `this` refers to the current object of that class. -* In an [extension function](extensions.md) or a [function literal with receiver](lambdas.md#function-literals-with-receiver) -`this` denotes the _receiver_ parameter that is passed on the left-hand side of a dot. -If `this` has no qualifiers, it refers to the _innermost enclosing scope_. To refer to `this` in other scopes, _label qualifiers_ are used: + For example, in the following code, `this.name` means the `name` property of the current `Language` object: + + ```kotlin + //sampleStart + class Language(val name: String) { + fun printName() { + println(this.name) + } + } + + fun main() { + val language = Language("Kotlin") + language.printName() + // Kotlin + } + //sampleEnd + ``` + {kotlin-runnable="true"} + +* In an [extension function](extensions.md) or a [function literal with receiver](lambdas.md#function-literals-with-receiver), +`this` refers to the receiver (the object with which the function works). + + In the following example, we call `lastCharacter()`on the string `"Kotlin"`. Inside the extension function, this refers + to `"Kotlin"`. This means that `this.length` is the length of `"Kotlin"`: + + ```kotlin + //sampleStart + fun String.lastCharacter(): Char { + println(this.length) + // 6 + return this[this.length - 1] + } + + fun main() { + println("Kotlin".lastCharacter()) + // n + } + //sampleEnd + ``` + {kotlin-runnable="true"} + +> In simple cases, you don't need to write `this` explicitly. Kotlin infers it from the current scope. +> Learn more about [](#implicit-this). +> +{style="tip"} -## Qualified this +## Qualified this -To access `this` from an outer scope (a [class](classes.md), [extension function](extensions.md), -or labeled [function literal with receiver](lambdas.md#function-literals-with-receiver)) you write `this@label`, - where `@label` is a [label](returns.md) on the scope `this` is meant to be from: +Kotlin code can have several possible `this` values at the same time. This happens when receiver scopes are nested. For +example, an inner class can access both its own object and the outer class object. In such cases, plain `this` refers +to the receiver of the _innermost enclosing scope_. To refer to a receiver from an outer scope, use a qualified `this`. + +To use a qualified `this`, add a label qualifier: ```kotlin -class A { // implicit label @A - inner class B { // implicit label @B - fun Int.foo() { // implicit label @foo - val a = this@A // A's this - val b = this@B // B's this +this@label +``` - val c = this // foo()'s receiver, an Int - val c1 = this@foo // foo()'s receiver, an Int +The label tells the compiler which receiver to access. You can use the name of an enclosing class or extension function. +For example, `this@foo` refers to the receiver of an enclosing extension function named `foo`. - val funLit = lambda@ fun String.() { - val d = this // funLit's receiver, a String - } +### Access an outer class from an inner class - val funLit2 = { s: String -> - // foo()'s receiver, since enclosing lambda expression - // doesn't have any receiver - val d1 = this - } +In an [inner class](nested-classes.md#inner-classes), plain `this` refers to the inner class instance. To access the outer class object, +use qualified `this`: + +```kotlin +//sampleStart +class User(val name: String) { + inner class Age(val value: Int) { + fun printInfo() { + + // Refers to the value property of the current Age object + println(this.value) + // 22 + + // Refers to the name property of the outer User object + println(this@User.name) + // Jane Doe } } } + +fun main() { + val user = User("Jane Doe") + val age = user.Age(22) + age.printInfo() +} +//sampleEnd +``` +{kotlin-runnable="true"} + +> Only inner classes hold a reference to an outer class instance. Regular [nested classes](nested-classes.md) don't have access to +> `this` from the outer class. +> +{style="note"} + +### Access a class from an extension function + +If you declare an extension function inside a class, two receivers are available: + +* The extension receiver: the value on which you call the extension function. +* The dispatch receiver: the current object of the class where you declare the extension function. + +Use qualified `this` to specify which receiver you need: + +```kotlin +//sampleStart +class User { + val prefix = "Name" + + fun String.formatName(): String { + return "${this@User.prefix}: ${this.uppercase()}" + } + + fun printUser() { + println("Jane Doe".formatName()) + } +} + +fun main() { + val user = User() + user.printUser() + // Name: JANE DOE +} +//sampleEnd ``` +{kotlin-runnable="true"} + +Here: + +* `this` refers to the extension receiver (the string `"Jane Doe"`). +* `this@User` refers to the current `User` object. +* `this@User.prefix` accesses the prefix property of the current `User` object. + +### Access a receiver from a lambda + +Unlike a regular lambda, a [lambda with receiver](lambdas.md#function-literals-with-receiver) has its own receiver. Therefore, `this` inside it +refers to that receiver. If a lambda with receiver is nested inside another receiver scope, add a label to the lambda +and use qualified `this` to specify which receiver you need: + +```kotlin +//sampleStart +class User(val name: String) { + fun printWithPrefix() { + val print: String.() -> Unit = stringLabel@ { + println("${this@stringLabel}: ${this@User.name}") + } + + print("User") + } +} + +fun main() { + val user = User("Jane Doe") + user.printWithPrefix() + // User: Jane Doe +} +//sampleEnd +``` +{kotlin-runnable="true"} + +Here: + +* `stringLabel@` labels the lambda. +* `this@stringLabel` refers to the string receiver of the lambda. +* `this@User` refers to the current `User` object. + +The label doesn't call anything or change how the lambda works. It only helps you refer to the lambda's receiver. + +### Access an anonymous object + +Since anonymous objects don’t have class names, you can't use a class name like `this@YourClassName` to refer +to it. Inside an anonymous object, use plain `this` to refer to the object: + +```kotlin +//sampleStart +interface UserPrinter { + fun print() +} + +fun printUser(printer: UserPrinter) { + printer.print() +} + +fun main() { + val printer = object : UserPrinter { + val name = "Jane Doe" + + override fun print() { + // Refers to the name property of the anonymous object + println(this.name) + } + } + printUser(printer) + // Jane Doe +} +//sampleEnd +``` +{kotlin-runnable="true"} + +> If you create an anonymous object inside another class, you can use qualified `this` to access the outer class object. +> Use it to access an outer receiver, not the anonymous object itself. +> +{style="tip"} + ## Implicit this From b2797c3e89ac90684780b8930acf8d7aadff1b30 Mon Sep 17 00:00:00 2001 From: "aleksandra.epanchintseva" Date: Mon, 6 Jul 2026 17:54:20 +0200 Subject: [PATCH 2/3] polishing --- docs/topics/this-expressions.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/topics/this-expressions.md b/docs/topics/this-expressions.md index 51006713ea5..3a61ea78f47 100644 --- a/docs/topics/this-expressions.md +++ b/docs/topics/this-expressions.md @@ -26,9 +26,10 @@ How you use `this` depends on the context: {kotlin-runnable="true"} * In an [extension function](extensions.md) or a [function literal with receiver](lambdas.md#function-literals-with-receiver), -`this` refers to the receiver (the object with which the function works). +`this` refers to the receiver. - In the following example, we call `lastCharacter()`on the string `"Kotlin"`. Inside the extension function, this refers + A _receiver_ is the object that the function works with. In the following example, we call `lastCharacter()`on the string + `"Kotlin"`. Therefore, `"Kotlin"` is the receiver. Inside the extension function, `this` refers to `"Kotlin"`. This means that `this.length` is the length of `"Kotlin"`: ```kotlin @@ -54,11 +55,11 @@ How you use `this` depends on the context: ## Qualified this -Kotlin code can have several possible `this` values at the same time. This happens when receiver scopes are nested. For +Your code can have several possible `this` values at the same time. This happens when receiver scopes are nested. For example, an inner class can access both its own object and the outer class object. In such cases, plain `this` refers to the receiver of the _innermost enclosing scope_. To refer to a receiver from an outer scope, use a qualified `this`. -To use a qualified `this`, add a label qualifier: +To use a qualified `this`, add a [label](returns.md) qualifier: ```kotlin this@label @@ -82,7 +83,7 @@ class User(val name: String) { println(this.value) // 22 - // Refers to the name property of the outer User object + // Refers to the name property of the outer User object println(this@User.name) // Jane Doe } @@ -137,11 +138,11 @@ fun main() { Here: -* `this` refers to the extension receiver (the string `"Jane Doe"`). +* `this` refers to the extension receiver (the `"Jane Doe"` string). * `this@User` refers to the current `User` object. * `this@User.prefix` accesses the prefix property of the current `User` object. -### Access a receiver from a lambda +### Access from a lambda Unlike a regular lambda, a [lambda with receiver](lambdas.md#function-literals-with-receiver) has its own receiver. Therefore, `this` inside it refers to that receiver. If a lambda with receiver is nested inside another receiver scope, add a label to the lambda @@ -178,7 +179,7 @@ The label doesn't call anything or change how the lambda works. It only helps yo ### Access an anonymous object -Since anonymous objects don’t have class names, you can't use a class name like `this@YourClassName` to refer +Since anonymous objects don’t have class names, you can't use a name like `this@YourClassName` to refer to it. Inside an anonymous object, use plain `this` to refer to the object: ```kotlin From beea7c1fa4e467965b6122bbf04e4e53c31060a6 Mon Sep 17 00:00:00 2001 From: "aleksandra.epanchintseva" Date: Wed, 8 Jul 2026 14:06:12 +0200 Subject: [PATCH 3/3] tech review --- docs/topics/this-expressions.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/topics/this-expressions.md b/docs/topics/this-expressions.md index 3a61ea78f47..fe5e8a69369 100644 --- a/docs/topics/this-expressions.md +++ b/docs/topics/this-expressions.md @@ -1,8 +1,6 @@ [//]: # (title: This expressions) -The `this` expression refers to the current object or receiver. - -How you use `this` depends on the context: +The `this` expression refers to the current receiver. How you use `this` depends on the context: * In a member of a [class](classes.md#inheritance), `this` refers to the current object of that class. @@ -28,7 +26,7 @@ How you use `this` depends on the context: * In an [extension function](extensions.md) or a [function literal with receiver](lambdas.md#function-literals-with-receiver), `this` refers to the receiver. - A _receiver_ is the object that the function works with. In the following example, we call `lastCharacter()`on the string + In the following example, we call `lastCharacter()`on the string `"Kotlin"`. Therefore, `"Kotlin"` is the receiver. Inside the extension function, `this` refers to `"Kotlin"`. This means that `this.length` is the length of `"Kotlin"`: @@ -48,16 +46,16 @@ How you use `this` depends on the context: ``` {kotlin-runnable="true"} -> In simple cases, you don't need to write `this` explicitly. Kotlin infers it from the current scope. +> In simple cases, you don't need to write `this` explicitly. Kotlin interprets it from the current scope. > Learn more about [](#implicit-this). > {style="tip"} ## Qualified this -Your code can have several possible `this` values at the same time. This happens when receiver scopes are nested. For -example, an inner class can access both its own object and the outer class object. In such cases, plain `this` refers -to the receiver of the _innermost enclosing scope_. To refer to a receiver from an outer scope, use a qualified `this`. +Your code can have several possible `this` values at the same time when receiver scopes are nested. For example, an inner +class can access both its own object and the outer class object. If `this` has no qualifier, it refers to the receiver +of the _innermost enclosing scope_. To refer to a receiver from an outer scope, use a qualified `this`. To use a qualified `this`, add a [label](returns.md) qualifier: @@ -179,7 +177,7 @@ The label doesn't call anything or change how the lambda works. It only helps yo ### Access an anonymous object -Since anonymous objects don’t have class names, you can't use a name like `this@YourClassName` to refer +Since anonymous objects don't have class names, you can't use a name like `this@YourClassName` to refer to it. Inside an anonymous object, use plain `this` to refer to the object: ```kotlin