skip to content

use for Closeable

use runs a block against a Closeable and closes it in a finally, even when the block throws — Kotlin's answer to try-with-resources. Interviewers ask because Kotlin has no dedicated syntax for it, so knowing the function is the whole answer.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

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

open as a page

How does `use` propagate its return value, and how do you correctly handle two resources (e.g. an input and an output stream) with `use`?

level: middleimportance: should knowfreq 55%

basics

~10 s

use returns whatever its lambda returns, so you can assign it directly. For two resources, nest one use inside another so both close in the right order.

open as a page

If both the `use` block and the resource's `close()` throw exceptions, which exception propagates, and what happens to the other?

level: middleimportance: should knowfreq 40%

basics

~10 s

The error from your block wins and is thrown. The error from closing is attached to it as a 'suppressed' exception so you don't lose it, but it doesn't replace the original.

open as a page

Contrast `use` with a manual `try/finally` and with scope functions like `apply`/`also`/`let`. When would you NOT reach for `use`?

level: seniorimportance: should knowfreq 45%

basics

~20 s

use is a focused try/finally that closes a resource; it isn't a general scope function. Don't use it for objects that aren't Closeable, or when the resource must outlive the block (e.g. you return it or a framework owns its lifecycle).

open as a page

What goes wrong when you return a lazy `Sequence` (e.g. from `lineSequence()`) out of a `use` block, and how do you consume file lines safely?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

A lazy sequence only reads when you iterate it. If you return it from use, the reader is already closed before you read, so iteration fails. Consume the lines inside the block, or use useLines.

open as a page