Reputation: 459
I have a problem with understanding how to implement extension function, which calls other functions inside the class. My goal is to implement extension function that calls in this case open()
, find()
and close()
.
Fridge
class is as follows:
class Fridge {
fun open() = println(1)
fun find(productName: String): Product {
println(productName)
return 4
}
fun close() = println(3)
}
I have no problem with writing single extension function lets say:
fun Double.addInt(i: Int) = this + i.toDouble()
But I'm confused with multiple funcions at once, also specified return type gets me confused. What I have is:
fun Fridge.take(productName: String): Product {
open()
find(productName)
close()
//return this.find(productName)
}
Where have i made a mistake? Right now I guess it's return type, but how to return Product
?
(This is a task from hyperskill
)
Upvotes: 3
Views: 189
Reputation: 18537
The traditional answer is to store the result in a temporary variable, so you can return it later:
fun Fridge.take(productName: String): Product {
open()
val result = find(productName)
close()
return result
}
Kotlin also provides a shorter alternative that you may find more or less clear:
fun Fridge.take(productName: String): Product {
open()
return find(productName)
.also{ close() }
}
This uses the also()
scope function, which simply returns the object it was called on (in this case, the Product we want to return). (I've used this for simple cases, such as logging; but I think it could be confusing for anything more complicated.)
LATER UPDATE:
I missed a big safety issue with the code above: what happens if there's a problem finding the product, and find()
throws an exception? It will exit the method immediately, leaving the fridge open!
That's usually a bad idea. In the case of a fridge, it could lead to your food getting warm; in other programs, leaving a resource open could prevent it being used again. The usual way to address this is with a try
…finally
block — which, coincidentally, gives another answer to the original problem:
fun Fridge.take(productName: String): Product {
open()
try {
return find(productName)
} finally {
close()
}
}
This will open the fridge, and try to find and return the product. But, whatever happens, if the fridge was opened, this will always close it.
Upvotes: 6
Reputation:
You can also use this
keyword here as follows:
fun Fridge.take(productName: String): Product {
this.open()
val prod = this.find(productName)
this.close()
return prod
}
Upvotes: 0