skip to content

What does the Kotlin standard library `use { }` function do, and why use it instead of manually calling `close()`?

level: juniorimportance: must knowfreq 70%

answer

  1. inline extension on Closeable / AutoCloseable
  2. closes in finally even on exception
  3. Kotlin's try-with-resources replacement
  4. returns the block's result
  5. resource passed as `it`

basics

~10 s

use { } runs your code with a resource (like a file or stream) and automatically closes it afterwards, even if your code throws an error. It saves you from forgetting to close it.

solid answer

~40 s

`use` is an inline extension function on `Closeable` (and on `AutoCloseable` since Kotlin 1.2 on JDK 7+). You call it on a resource and pass a lambda; the resource is the lambda receiver/argument, and `use` guarantees `close()` runs in a `finally` block whether the lambda returns normally or throws. It returns whatever the lambda returns. It is Kotlin's replacement for Java's try-with-resources, since Kotlin has no `try (…)` syntax. Typical use: `file.bufferedReader().use { it.readText() }`. Without it you must wrap the resource in `try/finally` yourself and remember to null-check and close in the right order, which is error-prone and leaks resources on the exception path.

code

kotlin · 2 lines
kotlin
val firstLine = File("log.txt").bufferedReader().use { it.readLine() }
// reader is already closed here, even if readLine() had thrown

go deeper

for a junior

Knows use opens-runs-closes a resource automatically and is safer than manual close.

for a middle

Names it as an inline extension on Closeable/AutoCloseable that closes in a finally and returns the block result.

for a senior

Explains why Kotlin chose a library function over language syntax and the inline/return semantics.

for a principal

Discusses resource-lifetime correctness across an API surface and codifies use as the team standard over hand-rolled try/finally.

## What `use` is `use` is an **extension function** in the Kotlin standard library (`kotlin.io`). An extension function adds a method to an existing type without modifying it. `use` is defined on `Closeable` (the `java.io.Closeable` interface) and, since Kotlin 1.2 targeting JDK 7+, also on `java.lang.AutoCloseable`. Both interfaces declare a `close()` method that releases an underlying resource such as a file handle, socket, or database connection. ## Why it exists Kotlin deliberately has **no `try-with-resources` syntax** like Java's `try (var r = …) { }`. Instead the language relies on this library function. `use` is the idiomatic Kotlin replacement. ## Signature and behaviour ```kotlin public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R ``` - It is **`inline`**: the lambda body is inlined at the call site, so there is no function-object allocation and `return`/`break` from inside the block behave naturally. - The receiver `T` is the resource; it is passed into `block` as the single argument (commonly accessed via the implicit `it`). - It returns `R`, whatever the `block` returns — so you can compute and return a value directly. - It calls `close()` in a **`finally`**, so the resource closes whether `block` succeeds or throws. Conceptually it expands to: ```kotlin val reader = file.bufferedReader() try { /* block, with reader as `it` */ } finally { reader.close() } ``` (The real implementation also suppresses a secondary exception thrown by `close()` if the block already threw — see follow-ups.) ## Typical usage ```kotlin val text = File("data.txt").bufferedReader().use { reader -> reader.readText() } ``` The `BufferedReader` is closed as soon as the lambda finishes, releasing the OS file handle. ## Why not manual `close()` If you write `val r = open(); r.read(); r.close()` and `read()` throws, `close()` never runs and you leak the handle. `use` removes that whole class of bugs.

  • What types can you call `use` on?
    Anything implementing `java.io.Closeable`, and since Kotlin 1.2 on JDK 7+ anything implementing `java.lang.AutoCloseable` (a broader set, e.g. JDBC `Connection`).
  • Does `use` swallow the exception from the block?
    No. If the block throws, that exception propagates out of `use` after the resource is closed.

Like a self-locking door: no matter how you leave the room (calmly or running out screaming), it locks behind you.

saying these in an interview costs you the question

  • Thinks `use` catches/swallows exceptions from the block
  • Says you still need to call `close()` manually inside the block
  • Confuses `use` with `also`/`apply` (scope functions that do not close anything)
  • Believes resource stays open after the lambda returns
  • Claims Kotlin has its own `try (…)` syntax

context