Defer in Kotlin

In Kotlin, we use the use function or try-with-resources construct to ensure that resources are properly closed. This is similar to the defer concept in other languages.

Let’s see how we can create a file, write to it, and then close it when we’re done:

import java.io.File

fun main() {
    // The 'use' function ensures that the file is closed after we're done with it
    File("/tmp/defer.txt").outputStream().use { file ->
        createFile(file)
        writeFile(file)
        // The file will be automatically closed here
    }
}

fun createFile(file: java.io.OutputStream) {
    println("creating")
    // File is already created by the 'outputStream()' function
}

fun writeFile(file: java.io.OutputStream) {
    println("writing")
    file.write("data\n".toByteArray())
}

In this example, the use function takes care of closing the file for us, similar to how defer works. The use function will close the resource (in this case, the file) even if an exception occurs.

Running the program confirms that the file operations are performed in the correct order:

$ kotlin defer.kt
creating
writing

It’s worth noting that in Kotlin, we don’t need to explicitly close the file or check for errors when closing, as the use function handles this for us. If any errors occur during file operations, they will be thrown as exceptions, which can be caught and handled as needed.

This approach ensures that resources are always properly managed and closed, preventing resource leaks and other issues that can arise from improperly managed file operations.