0
0
Kotlinprogramming~15 mins

This vs it receiver difference in Kotlin - Trade-offs & Expert Analysis

Choose your learning style9 modes available
Overview - This vs it receiver difference
What is it?
In Kotlin, 'this' and 'it' are special keywords used inside lambda expressions and functions to refer to the current object or parameter. 'this' refers to the instance of the class or the receiver object in a function or lambda with receiver. 'it' is an implicit name for a single parameter in a lambda when no explicit name is given. Both help write concise and readable code by avoiding explicit naming.
Why it matters
Without understanding the difference between 'this' and 'it', Kotlin code can become confusing or incorrect, especially when working with lambdas and extension functions. Knowing when to use each makes your code cleaner and prevents bugs related to referencing the wrong object or parameter. It also helps you read and write idiomatic Kotlin, which is important for collaboration and maintenance.
Where it fits
Before learning this, you should know basic Kotlin syntax, functions, and lambda expressions. After this, you can explore advanced Kotlin features like extension functions, higher-order functions, and DSLs (Domain Specific Languages) that heavily use receivers and lambdas.
Mental Model
Core Idea
'this' points to the current object or receiver, while 'it' is the default name for a single lambda parameter when no explicit name is given.
Think of it like...
Imagine you are in a room (the current object). When you say 'this', you mean the room you are standing in. When you say 'it', you mean the visitor who just entered the room without naming them.
┌───────────────┐
│   Class/Scope │
│  ┌─────────┐  │
│  │  this   │◀─┤ Points to current object
│  └─────────┘  │
│               │
│  Lambda with  │
│  single param │
│  ┌─────────┐  │
│  │   it    │◀─┤ Default name for single param
│  └─────────┘  │
└───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding 'this' keyword basics
🤔
Concept: 'this' refers to the current object instance inside a class or function.
In Kotlin, inside a class, 'this' refers to the current object. For example: class Person(val name: String) { fun greet() { println("Hello from ${this.name}") } } Here, 'this.name' accesses the 'name' property of the current Person object.
Result
Calling greet() on a Person object prints 'Hello from '.
Understanding 'this' is essential because it lets you refer to the current object clearly, especially when variable names might overlap.
2
FoundationIntroducing 'it' in lambda expressions
🤔
Concept: 'it' is the implicit name for a single parameter in a lambda when no explicit name is given.
When you write a lambda with one parameter and don't name it, Kotlin uses 'it' automatically: val numbers = listOf(1, 2, 3) numbers.forEach { println(it) } Here, 'it' represents each element in the list during iteration.
Result
The program prints 1, then 2, then 3 each on a new line.
Knowing 'it' lets you write shorter lambdas without naming parameters, making code concise and readable.
3
IntermediateDifference between 'this' and 'it' in lambdas
🤔Before reading on: In a lambda with receiver, do you think 'this' refers to the lambda parameter or the receiver object? Commit to your answer.
Concept: 'this' in a lambda with receiver points to the receiver object, while 'it' refers to the lambda's single parameter.
Kotlin allows lambdas with receivers, where 'this' refers to the receiver object: val stringBuilder = StringBuilder().apply { append("Hello") // 'this' is StringBuilder } In contrast, in a normal lambda with one parameter: listOf(1, 2, 3).forEach { println(it) // 'it' is the current element } If you mix them, 'this' and 'it' refer to different things.
Result
'this' accesses the receiver's members; 'it' accesses the lambda parameter.
Understanding this difference prevents confusion when reading or writing lambdas with receivers versus normal lambdas.
4
IntermediateExplicit naming vs implicit 'it' in lambdas
🤔Before reading on: Do you think you can use both 'it' and an explicit parameter name in the same lambda? Commit to your answer.
Concept: You can name lambda parameters explicitly to avoid using 'it', especially when multiple parameters exist.
For example: listOf(1, 2, 3).forEach { number -> println(number) // Explicit name instead of 'it' } If you name parameters, 'it' is not available. For multiple parameters, you must name them explicitly.
Result
The lambda uses the explicit parameter name, improving clarity.
Knowing when to use 'it' or explicit names helps write clearer code, especially in complex lambdas.
5
IntermediateUsing 'this' in nested lambdas
🤔Before reading on: In nested lambdas, does 'this' always refer to the innermost receiver? Commit to your answer.
Concept: 'this' refers to the closest receiver in scope; you can qualify it to access outer receivers.
Example: class Outer { val name = "Outer" fun outerFunc() { val inner = Inner() inner.innerFunc { println(this.name) // 'this' is Inner's receiver println(this@Outer.name) // qualified 'this' refers to Outer } } } class Inner { val name = "Inner" fun innerFunc(block: Inner.() -> Unit) { this.block() } } Here, 'this' inside the lambda is Inner, but 'this@Outer' accesses Outer.
Result
You can access different receivers by qualifying 'this'.
Knowing how to qualify 'this' avoids confusion and bugs in nested scopes.
6
AdvancedWhen 'it' is unavailable in lambdas with receivers
🤔Before reading on: Can you use 'it' inside a lambda with receiver? Commit to your answer.
Concept: In lambdas with receivers, 'it' is not available because the lambda has an implicit receiver instead of a parameter.
For example: val result = with(StringBuilder()) { append("Hello") // 'it' is not available here toString() } If you want a parameter and a receiver, you must name the parameter explicitly or use different constructs.
Result
'it' is undefined in lambdas with receivers, preventing ambiguity.
Understanding this prevents errors when switching between lambda types.
7
ExpertHow Kotlin resolves 'this' and 'it' in complex scopes
🤔Before reading on: In a lambda inside a class method, does 'this' always refer to the lambda receiver or the class instance? Commit to your answer.
Concept: Kotlin resolves 'this' by looking at the closest receiver in scope, and you can qualify 'this' to specify which receiver you mean. 'it' always refers to the single lambda parameter if present.
Consider: class Example { val name = "Example" fun run() { val list = listOf(1, 2) list.forEach { println(it) // 'it' is list element println(this.name) // 'this' is Example instance val lambdaWithReceiver: StringBuilder.() -> Unit = { append(it) // 'it' from outer lambda append(this@Example.name) // qualified 'this' } StringBuilder().lambdaWithReceiver() } } } Here, Kotlin carefully distinguishes 'this' and 'it' based on scope and qualification.
Result
You can precisely control which 'this' or 'it' you refer to, avoiding ambiguity.
Mastering scope resolution of 'this' and 'it' is key to writing complex, bug-free Kotlin code.
Under the Hood
'this' is a reference to the current receiver object stored in the call stack or context during function or lambda execution. Lambdas with receivers are compiled as functions with an implicit receiver parameter, allowing 'this' to access receiver members directly. 'it' is a compiler-generated name for the single lambda parameter when no explicit name is given, simplifying code. The Kotlin compiler manages these references to resolve them correctly based on lexical scope and receiver hierarchy.
Why designed this way?
Kotlin introduced lambdas with receivers and implicit 'it' to reduce boilerplate and improve readability. Using 'this' as a receiver allows DSL-like syntax, making code expressive and concise. The implicit 'it' parameter avoids unnecessary naming for simple lambdas. This design balances clarity and brevity, inspired by functional programming and builder patterns, while maintaining type safety and explicit control when needed.
┌─────────────────────────────┐
│       Call Stack Frame       │
│ ┌─────────────────────────┐ │
│ │ Receiver Object (this)  │ │
│ └─────────────────────────┘ │
│                             │
│ ┌─────────────────────────┐ │
│ │ Lambda Parameter (it)   │ │
│ └─────────────────────────┘ │
│                             │
│ Compiler resolves 'this' and 'it' based on scope and context
└─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does 'it' always refer to the current object like 'this'? Commit to yes or no.
Common Belief:'it' is just another way to say 'this' inside lambdas.
Tap to reveal reality
Reality:'it' is the implicit name for a single lambda parameter, not the current object. 'this' refers to the receiver object or class instance.
Why it matters:Confusing 'it' and 'this' leads to referencing wrong data, causing bugs and unexpected behavior.
Quick: Can you use 'it' inside a lambda with receiver? Commit to yes or no.
Common Belief:'it' is always available inside any lambda, including lambdas with receivers.
Tap to reveal reality
Reality:In lambdas with receivers, 'it' is not available because the lambda uses an implicit receiver instead of a parameter.
Why it matters:Trying to use 'it' in such lambdas causes compilation errors and confusion about parameter access.
Quick: In nested lambdas, does 'this' always refer to the innermost receiver? Commit to yes or no.
Common Belief:'this' always points to the innermost lambda's receiver without exception.
Tap to reveal reality
Reality:'this' refers to the closest receiver, but you can qualify it (e.g., this@Outer) to access outer receivers.
Why it matters:Not knowing this leads to bugs when accessing properties or functions from outer scopes.
Quick: Is naming lambda parameters optional when you want to use 'it'? Commit to yes or no.
Common Belief:You can use 'it' even if you explicitly name lambda parameters.
Tap to reveal reality
Reality:If you name lambda parameters explicitly, 'it' is not available in that lambda.
Why it matters:Misunderstanding this causes confusion about parameter names and lambda behavior.
Expert Zone
1
In lambdas with receivers, 'this' can refer to different types depending on context, enabling powerful DSLs but requiring careful scope management.
2
Qualified 'this' (like this@Label) is essential in nested scopes to avoid ambiguity and access the correct receiver.
3
The Kotlin compiler optimizes lambdas with receivers differently than normal lambdas, affecting performance and bytecode structure subtly.
When NOT to use
Avoid lambdas with receivers when you need multiple parameters or when implicit receivers cause confusion. Use regular lambdas with explicit parameters instead. Also, avoid overusing 'it' in complex lambdas where explicit names improve readability.
Production Patterns
In production, lambdas with receivers are widely used in Kotlin DSLs like HTML builders, Gradle scripts, and Android UI code. 'it' is common in simple collection operations. Experts combine qualified 'this' and explicit parameter naming to write clear, maintainable code in complex nested scenarios.
Connections
JavaScript 'this' keyword
Similar concept of 'this' as current object context, but JavaScript's 'this' is dynamic while Kotlin's is lexical.
Understanding Kotlin's lexical 'this' clarifies why it behaves more predictably than JavaScript's 'this', helping developers avoid common JS pitfalls.
Functional programming closures
'it' as an implicit parameter name is a convenience in functional programming style lambdas and closures.
Recognizing 'it' as a closure parameter connects Kotlin lambdas to broader functional programming concepts, aiding comprehension of lambda expressions.
Human conversation context
'this' and 'it' mirror how people use pronouns to refer to known subjects or new objects in conversation.
Seeing 'this' and 'it' as linguistic tools for context helps understand their role in code as references to objects or parameters, improving intuitive grasp.
Common Pitfalls
#1Using 'it' inside a lambda with receiver causes errors.
Wrong approach:val result = with(StringBuilder()) { append("Hello") println(it) // Error: 'it' is unresolved }
Correct approach:val result = with(StringBuilder()) { append("Hello") // Use explicit parameter or receiver members only }
Root cause:Misunderstanding that lambdas with receivers do not have an implicit 'it' parameter.
#2Confusing 'this' with lambda parameter in nested scopes.
Wrong approach:class Example { val name = "Outer" fun test() { listOf(1).forEach { println(this.name) // Error: 'this' is not the list element } } }
Correct approach:class Example { val name = "Outer" fun test() { listOf(1).forEach { element -> println(element) // Correct: use parameter println(this.name) // 'this' refers to Example } } }
Root cause:Assuming 'this' refers to lambda parameter instead of the enclosing class instance.
#3Using 'it' and explicit parameter name together in the same lambda.
Wrong approach:listOf(1).forEach { it, number -> println(number) } // Syntax error
Correct approach:listOf(1).forEach { number -> println(number) }
Root cause:Misunderstanding that 'it' is only available when no explicit parameter name is given.
Key Takeaways
'this' refers to the current object or receiver, while 'it' is the implicit name for a single lambda parameter.
Lambdas with receivers use 'this' to access the receiver object, but do not have an 'it' parameter.
Explicitly naming lambda parameters disables the implicit 'it', improving clarity in complex lambdas.
Qualified 'this' (like this@Label) is essential to access outer receivers in nested scopes.
Mastering the difference between 'this' and 'it' helps write clear, concise, and bug-free Kotlin code.