📖 Scenario: Imagine you want to build a simple text formatter that can change the case of a string and add punctuation. Using Kotlin's lambda with receiver, you can create a neat way to apply these changes inside a block that feels like working directly on the string.
🎯 Goal: You will create a lambda with receiver that modifies a string by changing its case and adding punctuation, then apply it to a sample string and print the result.
📋 What You'll Learn
Create a variable called text with the value "hello kotlin"
Create a lambda with receiver called formatter of type String.() -> String
Inside formatter, convert the string to uppercase and add an exclamation mark at the end
Call formatter on text and store the result in formattedText
Print the value of formattedText
💡 Why This Matters
🌍 Real World
Lambda with receiver is useful in Kotlin DSLs (domain-specific languages) and builder patterns where you want to write clean and readable code that looks like it is working inside an object.
💼 Career
Understanding lambda with receiver helps you work with Kotlin libraries and frameworks that use this feature, such as Android development with Kotlin, making your code more concise and expressive.
Progress0 / 4 steps
1
Create the initial string
Create a variable called text and set it to the string "hello kotlin".
Kotlin
Hint
Use val text = "hello kotlin" to create the string variable.
2
Create the lambda with receiver
Create a lambda with receiver called formatter of type String.() -> String. Inside it, convert the string to uppercase and add an exclamation mark at the end.
Kotlin
Hint
Define formatter as val formatter: String.() -> String = { this.uppercase() + "!" }.
3
Apply the lambda with receiver
Call the lambda formatter on the variable text and store the result in a variable called formattedText.
Kotlin
Hint
Use val formattedText = text.formatter() to apply the lambda.
4
Print the formatted text
Print the value of the variable formattedText.
Kotlin
Hint
Use println(formattedText) to display the result.
Practice
(1/5)
1. What is the main benefit of using a lambda with receiver in Kotlin?
easy
A. It disables access to the outer scope variables.
B. It automatically creates a new object for each lambda execution.
C. It forces all lambdas to return Unit type.
D. It allows you to call methods on an object without repeating the object name inside the lambda.
Solution
Step 1: Understand lambda with receiver purpose
A lambda with receiver lets you write code blocks that behave as if they belong to an object, so you can call its methods directly.
Step 2: Identify the benefit
This means you don't have to repeat the object name inside the lambda, making code cleaner and easier to read.
Final Answer:
It allows you to call methods on an object without repeating the object name inside the lambda. -> Option D
Quick Check:
Lambda with receiver = cleaner calls [OK]
Hint: Remember: receiver means 'this' inside lambda [OK]
Common Mistakes:
Thinking it creates new objects automatically
Assuming it restricts return types
Believing it blocks outer variables
2. Which of the following is the correct syntax to declare a lambda with receiver of type StringBuilder in Kotlin?
easy
A. val lambda: () -> StringBuilder = { append("Hello") }
B. val lambda: (StringBuilder) -> Unit = { append("Hello") }
C. val lambda: StringBuilder.() -> Unit = { append("Hello") }
D. val lambda: StringBuilder -> Unit = { append("Hello") }
Solution
Step 1: Recall lambda with receiver syntax
A lambda with receiver is declared by specifying the receiver type followed by a dot and then the function type, like StringBuilder.() -> Unit.
Step 2: Match syntax with options
val lambda: StringBuilder.() -> Unit = { append("Hello") } matches this syntax and uses append("Hello") inside the lambda, which is valid for StringBuilder.
Final Answer:
val lambda: StringBuilder.() -> Unit = { append("Hello") } -> Option C
Quick Check:
Receiver syntax = Type.() -> ReturnType [OK]
Hint: Receiver lambdas use Type.() -> ReturnType syntax [OK]
Common Mistakes:
Confusing parameter lambdas with receiver lambdas
Missing the dot after the receiver type
Using arrow without parentheses
3. What is the output of the following Kotlin code?
val buildString: StringBuilder.() -> Unit = {
append("Hi")
append(", ")
append("there!")
}
val result = StringBuilder().apply(buildString).toString()
println(result)
medium
A. Compilation error
B. Hi, there!
C. Hi there!
D. StringBuilder@<hashcode>
Solution
Step 1: Understand the lambda with receiver usage
The lambda buildString is a StringBuilder receiver lambda that appends "Hi", ", ", and "there!" to the StringBuilder.
Step 2: Apply lambda and convert to string
The apply function runs the lambda on a new StringBuilder instance, then toString() converts it to the string "Hi, there!".
Final Answer:
Hi, there! -> Option B
Quick Check:
apply + receiver lambda = built string [OK]
Hint: apply runs lambda on object, returns object [OK]
Common Mistakes:
Expecting default toString output of StringBuilder
Missing commas in output
Thinking lambda returns string directly
4. Identify the error in this Kotlin code using a lambda with receiver:
val printLength: String.() -> Unit = {
println(length())
}
"Hello".printLength()
medium
A. Cannot call length() as a function; length is a property.
B. Lambda with receiver must return a value.
C. String cannot be a receiver type.
D. Missing parentheses when calling printLength.
Solution
Step 1: Check usage of length inside lambda
In Kotlin, length is a property of String, not a function, so calling length() causes an error.
Step 2: Verify other parts
The lambda correctly uses String as receiver and returns Unit, and calling printLength without parentheses is valid syntax.
Final Answer:
Cannot call length() as a function; length is a property. -> Option A
Quick Check:
Properties accessed without () [OK]
Hint: Remember: properties have no parentheses [OK]
Common Mistakes:
Using parentheses with properties
Thinking receiver type can't be String
Forgetting lambda return type can be Unit
5. You want to create a function buildHtml that uses a lambda with receiver to build an HTML string with nested tags. Which approach correctly uses lambda with receiver to achieve this?
fun buildHtml(block: StringBuilder.() -> Unit): String {
val sb = StringBuilder()
sb.block()
return sb.toString()
}
val html = buildHtml {
append("")
append("")
append("Hello")
append("")
append("")
}
println(html)
hard
A. This code correctly uses a lambda with receiver to build the HTML string.
B. The lambda should have a receiver of type HtmlBuilder, not StringBuilder.
C. You must return the lambda result explicitly inside buildHtml.
D. The lambda cannot be called with sb.block(); use block(sb) instead.
Solution
Step 1: Analyze the function signature and call
The function buildHtml takes a lambda with receiver StringBuilder.() -> Unit and calls it on sb using sb.block(), which is correct syntax.
Step 2: Check the lambda body and return
The lambda appends HTML tags to StringBuilder, and the function returns the built string with sb.toString(), which is the expected behavior.
Final Answer:
This code correctly uses a lambda with receiver to build the HTML string. -> Option A
Quick Check:
Lambda with receiver called on object = correct [OK]
Hint: Call receiver lambda with object.lambda() syntax [OK]
Common Mistakes:
Confusing lambda with receiver and lambda with parameter
Forgetting to call lambda on the object
Expecting lambda to return string directly
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.