yras8
yras8

Reputation: 459

Implement extension function Kotlin with couple functions from class

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 )

enter image description here

Upvotes: 3

Views: 189

Answers (2)

gidds
gidds

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 tryfinally 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

user12585593
user12585593

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

Related Questions