Extensions and scope functions
Extensions and scope functions
A report helper may fit naturally as a call on a score, while configuring an object can benefit from a short scope block. Extension functions add call syntax without modifying a class. Let, run, with, apply and also each choose a receiver form and a return value.
What you’ll learn
- Define an extension and read its receiver.
- Choose the return contract of let or apply.
Extensions and scope functions in the example
Extension call
A report helper may fit naturally as a call on a score, while configuring an object can benefit from a short scope block.
Extension callConfigure receiver
Extensions are resolved from the declared receiver type and do not add stored fields.
Configure receiverChoose result type
The extension compares 80 with the threshold.
Choose result type
Understand extensions and scope functions
Extensions are resolved from the declared receiver type and do not add stored fields. Let uses it and returns the lambda result; apply uses this and returns the receiver. Avoid deeply nesting scope functions until it and this lose an obvious meaning.
Follow extensions and scope functions
Save the complete source as Main.kt and use the Kotlin/JVM environment. No separate input file is needed.
Kotlin/JVM · complete program
fun Int.isPassing(): Boolean = this >= 75
fun main() {
println(80.isPassing())
val names = mutableListOf<String>().apply { add("Diya") }
val count = names.let { it.size }
println(count)
}Expected output
true
1Follow the execution
The extension compares 80 with the threshold. Apply configures and returns the same mutable list; let computes its size and returns an Int. These two calls have different result types despite their similar block syntax.
Try this in the Kotlin compiler by pasting the complete program.
Practice: Extensions and scope functions
Your task: What does apply return in this example?
Kotlin/JVM · complete program
fun Int.isPassing(): Boolean = this >= 75
fun main() {
println(80.isPassing())
val names = mutableListOf<String>().apply { add("Diya") }
val count = names.let { it.size }
println(count)
}Worked answer
It returns the configured list receiver, not the result of add. That is why names remains a list.
Extensions and scope functions: the important boundary
Existing members can take precedence over matching extensions. Scope functions do not perform asynchronous scheduling or make mutation atomic. Use them when the receiver and returned value remain clear.
Check your understanding
Extensions and scope functions: what to keep in mind
It returns the configured list receiver, not the result of add. That is why names remains a list. Existing members can take precedence over matching extensions.
Further reading: official Kotlin documentation for this topic.
Reaching the recap and completing the quizzes are separate milestones.