在Kotlin中有没有类似的东西可以提供和斯威夫特关键字“推迟”一样的能力?
defer关键字的作用是,它确保defer块中的代码在从函数返回之前得到执行。
下面是一个假设Kotlin中存在defer关键字的示例。
class MyClass {
var timeStamp = 0L
fun isEdible(fruit: Fruit): Boolean {
defer {
timeStamp = System.currentTimeMillis()
}
if (fruit.isExpired) {
return false
}
if (fruit.isRipe) {
return true
}
return false
}
}
在上面的例子中,无论函数在什么点返回,defer
中的块都会被执行,timestamp的值也会被更新,就在函数结束之前。
我知道Java中有finally {}
关键字与try{} catch{}
沿着使用,但这并不是defer所提供的。
5条答案
按热度按时间7cjasjjr1#
在Kotlin中没有这样的关键字,但是你可以自己构造一个类似的结构,类似于下面这样(注意这并不处理延迟块中的异常):
然后,您可以像这样使用它:
ebdffaop2#
最接近的等价物是
try
/finally
。如果没有抛出异常,则不需要catch
。在Swift中,
defer
通常用来确保你不会忘记清理某种资源(文件句柄、数据库连接、共享内存Map等)。为此,Kotlin使用with
,它接受一个闭包,资源作为参数传递给闭包。资源在闭包的生命周期内有效,并在结束时自动关闭。bxgwgixi3#
包含异常处理的解决方案:
IMHO,
defer
功能的要点是执行延迟的操作,而不管以前抛出的异常。用法:
soat7uwm4#
我今天遇到了同样的问题。
虽然我认为marstran提供的答案是好的,但我决定稍微重构一下。
我通过直接在
deffered
函数中使用列表来摆脱Deferrable
类。这也解决了整个Deferrable
对象被传递给需要调用it.defer
/d.defer
的调用代码的问题。在这个版本中,可变列表的add
方法被直接传递给lambda,从而允许代码更接近它的go/快速版本。为了解决mvndaai提出的使用
Stack
的建议,我决定在列表中调用.asReversed()
。也许Kotlin中有一个LI-FO类型,在非JVM变体中也可用,但如果没有,我认为这是一个很好的解决方案。给定的样本将看起来像:
z18hc3ub5#
如果类是
Closeable
,则可以使用use block
: