使用类中的耦合函数实现扩展函数Kotlin

使用类中的耦合函数实现扩展函数Kotlin,kotlin,Kotlin,我在理解如何实现扩展函数时遇到问题,扩展函数调用类内的其他函数。我的目标是实现扩展函数,在这种情况下调用open(),find()和close() 冰箱等级如下: class Fridge { fun open() = println(1) fun find(productName: String): Product { println(productName) return 4 } fun close() = println(3

我在理解如何实现扩展函数时遇到问题,扩展函数调用类内的其他函数。我的目标是实现扩展函数,在这种情况下调用
open()
find()
close()

冰箱
等级如下:

class Fridge {
    fun open() = println(1)
    fun find(productName: String): Product {
        println(productName)
        return 4
    }

    fun close() = println(3)
}
fun Fridge.take(productName: String): Product {
    this.open()
    val prod = this.find(productName)
    this.close()
    return prod  

}
我对编写单个扩展函数没有问题,比如:

fun Double.addInt(i:Int)=this+i.toDouble()

但我对同时使用多个函数感到困惑,同时指定的返回类型也让我感到困惑。我得到的是:

fun Fridge.take(productName: String): Product {
    open()
    find(productName)
    close()
    //return this.find(productName)
}
我哪里出错了?现在我猜是退货类型,但是如何退货产品呢

(这是来自
hyperskill
的任务)


传统的解决方法是将结果存储在临时变量中,以便稍后返回:

fun Fridge.take(productName: String): Product {
    open()
    val result = find(productName)
    close()
    return result
}
Kotlin还提供了一个简短的备选方案,您可能会或多或少地发现:

fun Fridge.take(productName: String): Product {
    open()
    return find(productName)
           .also{ close() }
}
这使用了scope函数,它只返回调用它的对象(在本例中,是我们想要返回的产品)。  (我已经在一些简单的情况下使用过这个方法,比如日志记录;但是我认为对于任何更复杂的情况,它都可能会让人困惑。)

稍后更新:

我忽略了上面代码的一个重大安全问题:如果查找产品时出现问题,并且
find()
抛出异常,会发生什么?  它将立即退出该方法,保持冰箱打开

这通常是个坏主意。  在冰箱的情况下,它可能会导致你的食物变热;在其他程序中,将资源保持打开状态可能会阻止它再次被使用。  解决这一问题的通常方法是使用
try
finally
块-巧合的是,它给出了原始问题的另一个答案:

fun Fridge.take(productName: String): Product {
    open()
    try {
        return find(productName)
    } finally {
        close()
    }
}

这将打开冰箱,尝试查找并退回产品。  但是,无论发生什么情况,如果冰箱被打开,它总是会被关闭。

你也可以在这里使用
这个
关键字,如下所示:

class Fridge {
    fun open() = println(1)
    fun find(productName: String): Product {
        println(productName)
        return 4
    }

    fun close() = println(3)
}
fun Fridge.take(productName: String): Product {
    this.open()
    val prod = this.find(productName)
    this.close()
    return prod  

}