Kotlin相当于Swift的defer关键字

时间:2018-07-18 21:09:41

标签: android swift kotlin keyword

Kotlin中是否有类似功能可以提供与Swift关键字“ defer”相同的功能?

延迟关键字的作用是,它确保延迟块内的代码在从函数返回之前得到执行。

下面是一个示例,假设det关键字存在于Kotlin中。

    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内的块都会被执行,并且时间戳记的值将在函数结束之前被更新。

我知道Java与finally {}一起使用了try{} catch{}关键字,但这并不是defer所提供的。

2 个答案:

答案 0 :(得分:3)

最接近的等效项是try / finally。如果没有引发异常,则catch是不必要的。

try {
    println("do something")
    // ... the rest of your method body here
}
finally {
    println("Don't forget about me!");
}

在Swift中,defer通常用于确保您不会忘记清理某种资源或其他资源(文件句柄,数据库连接,共享内存映射等)。为此,Kotlin使用with,它带有一个闭包,资源作为参数传递给该闭包。该资源在关闭的整个有效期内有效,并在结束时自动关闭。

FileWriter("test.txt")
  .use { it.write("something") }
// File is closed by now

答案 1 :(得分:2)

Kotlin中没有这样的关键字,但是您可以自己构建一个结构,该结构将非常相似地工作。这样的事情(请注意,这不会处理延迟块中的异常):

class Deferrable {
    private val actions: MutableList<() -> Unit> = mutableListOf()

    fun defer(f: () -> Unit) {
        actions.add(f)
    }

    fun execute() {
        actions.forEach { it() }
    }
}

fun <T> defer(f: (Deferrable) -> T): T {
    val deferrable = Deferrable()
    try {
        return f(deferrable)
    } finally {
        deferrable.execute()
    }
}

然后您可以像这样使用它:

class MyClass {

    var timeStamp = 0L

    fun isEdible(fruit: Fruit): Boolean = defer { d ->
      d.defer { 
       timeStamp = System.currentTimeMillis()
      }
      if (fruit.isExpired) {
         return false
      }
      if (fruit.isRipe) {
        return true
      }
      return false
    }
}