Extension function syntax in Kotlin - Time & Space Complexity
We want to understand how the time it takes to run an extension function changes as the input grows.
How does adding an extension function affect the work done when called on different input sizes?
Analyze the time complexity of the following Kotlin extension function.
fun List<Int>.sumElements(): Int {
var sum = 0
for (element in this) {
sum += element
}
return sum
}
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers.sumElements())
}
This code adds a new function to List<Int> that sums all its elements.
Look at what repeats when the function runs.
- Primary operation: Looping through each element in the list.
- How many times: Once for every item in the list.
As the list gets bigger, the function does more work by adding more numbers.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 additions |
| 100 | 100 additions |
| 1000 | 1000 additions |
Pattern observation: The work grows directly with the number of items.
Time Complexity: O(n)
This means the time to run grows in a straight line with the list size.
[X] Wrong: "Extension functions run instantly no matter the input size."
[OK] Correct: Even though the function is added outside the class, it still runs the code inside, which depends on the input size.
Knowing how extension functions behave helps you explain your code clearly and understand performance when adding new features.
"What if the extension function called another function inside that also loops over the list? How would the time complexity change?"
Practice
greet for the String type in Kotlin?Solution
Step 1: Understand extension function syntax
Extension functions use the syntaxfun ReceiverType.functionName(). Here,Stringis the receiver type.Step 2: Match the syntax with options
fun String.greet() { println("Hello, $this") } correctly usesfun String.greet(). Other options do not follow this syntax.Final Answer:
fun String.greet() { println("Hello, $this") } -> Option CQuick Check:
Extension function syntax = fun ReceiverType.functionName() [OK]
- Using 'extension' keyword which doesn't exist
- Placing receiver type as function parameter
- Missing receiver type before function name
square for Int that returns the square of the number?Solution
Step 1: Check extension function declaration with return type
The syntax isfun ReceiverType.functionName(): ReturnType = expression. fun Int.square(): Int = this * this matches this.Step 2: Verify usage of 'this' and return
fun Int.square(): Int = this * this correctly usesthis * thisand returns Int. fun Int.square() { this * this } uses braces (block body) but misses return statement, thus returns Unit. fun Int.square() = Int * Int uses invalidInt * Int.Final Answer:
fun Int.square(): Int = this * this -> Option AQuick Check:
Extension function with return type = fun ReceiverType.functionName(): Type [OK]
- Placing receiver type as function parameter
- Using braces without return in expression body
- Incorrect return type placement
fun String.shout() = this.uppercase() + "!"
fun main() {
val word = "hello"
println(word.shout())
}Solution
Step 1: Understand the extension function behavior
The extension functionshoutconverts the string to uppercase and adds an exclamation mark.Step 2: Apply the function to the string "hello"
Callingword.shout()returns "HELLO!" which is printed.Final Answer:
HELLO! -> Option BQuick Check:
Extension function output = uppercase + "!" [OK]
- Assuming original string changes
- Ignoring uppercase conversion
- Thinking extension functions modify original object
fun Int.double {
return this * 2
}Solution
Step 1: Check function declaration syntax
Functions must have parentheses after the name, even if no parameters are present. Here,doublemisses parentheses.Step 2: Verify other parts
Usingthisis valid in extension functions. Return statements are allowed. Extension functions can be declared for Int.Final Answer:
Missing parentheses after function name -> Option AQuick Check:
Function declaration requires parentheses () [OK]
- Omitting parentheses in function declaration
- Misunderstanding 'this' usage
- Thinking return is disallowed
isEven() to Int? (nullable Int) that returns true if the number is even, and false if it's odd or null. Which is the correct way to declare this extension function?Solution
Step 1: Understand nullable receiver type
To extend nullable Int, useInt?as receiver type. fun Int?.isEven(): Boolean = this != null && this % 2 == 0 does this correctly.Step 2: Check logic for null and even check
fun Int?.isEven(): Boolean = this != null && this % 2 == 0 uses concise expression: returns false if null, true if even. fun Int?.isEven(): Boolean { if (this == null) return false else return this % 2 != 0 } is verbose but has incorrect logic (returns true for odd). fun Int.isEven(): Boolean = this % 2 == 0 || this == null incorrectly uses non-nullable receiver and wrong logic. fun Int.isEven(): Boolean = this % 2 == 0 ignores null.Final Answer:
fun Int?.isEven(): Boolean = this != null && this % 2 == 0 -> Option DQuick Check:
Nullable receiver uses '?' and checks null explicitly [OK]
- Not using nullable receiver type for Int?
- Ignoring null checks inside function
- Using non-nullable receiver for nullable types
Ready to prove it?
Pass the test and this pattern moves unknown
