What does the stdlib `use` function do, and why is it preferred over manually calling `close()` on a resource?
answer
- inline extension on Closeable/AutoCloseable
- close() in finally, always
- addSuppressed keeps original error
- Kotlin's try-with-resources
- returns the lambda's value
basics
~10 suse runs your code with a resource like a file, then automatically closes it afterward, even if an error happens. It saves you from forgetting to close it yourself.
solid answer
~40 s`use` is an inline extension function on `Closeable`/`AutoCloseable`. You write `reader.use { r -> ... }`; it executes the lambda, then guarantees `close()` is called in a `finally` block whether the block returns normally or throws. This is Kotlin's equivalent of Java's try-with-resources. If the block throws and `close()` also throws, the close exception is added as a suppressed exception on the original (via `addSuppressed`), so the original error is not lost. Because `use` is `inline`, the lambda body is inlined at the call site with no extra object allocation. The return value of `use` is whatever the lambda returns, so you can compute and return a result directly: `val text = file.bufferedReader().use { it.readText() }`. Always prefer it over manual `try/finally { close() }`.
code
kotlin · 2 linesval lines: List<String> = File("in.txt").bufferedReader().use { it.readLines() }
// reader is closed here, even if readLines() throwsgo deeper
Knows use auto-closes the resource and replaces manual close().
Explains the finally semantics and that use returns the lambda value.
Discusses addSuppressed, inline (no allocation), and the AutoCloseable overload.
Frames use as the stdlib's deliberate mapping of try-with-resources onto an inline function, and reasons about exception-masking guarantees in library APIs.
## What `use` is `use` is a standard-library **extension function** declared (roughly) as `inline fun <T : Closeable?, R> T.use(block: (T) -> R): R`. There is also an overload for `AutoCloseable`. It models **scoped resource management**: a resource is acquired, used inside a block, then deterministically released. ## Why it exists Files, sockets, streams, and database connections hold OS-level handles that must be released. If you forget to call `close()`, you leak handles. Manual `try/finally` is verbose and easy to get wrong (e.g. swallowing the real exception). `use` packages the correct pattern once. ## How it works internally Conceptually: ```kotlin inline fun <T : Closeable?, R> T.use(block: (T) -> R): R { var exception: Throwable? = null try { return block(this) } catch (e: Throwable) { exception = e throw e } finally { when { this == null -> {} exception == null -> this.close() else -> try { this.close() } catch (closeEx: Throwable) { exception.addSuppressed(closeEx) } } } } ``` Key points: - **`finally`** guarantees `close()` runs on normal return *and* on exception. - If the block threw and `close()` *also* throws, the close exception is attached with **`addSuppressed`** so the primary failure is preserved. You can see it later via `Throwable.suppressed`. - It is **`inline`**, so the lambda is inlined — no `Function` object is allocated and `return`/`break` behave naturally. ## Typical usage ```kotlin val text = File("data.txt").bufferedReader().use { reader -> reader.readText() } ``` The value of the `use` expression is the lambda's last expression, so you can return computed data straight out of it. ## Relationship to Java This is Kotlin's counterpart to Java's **try-with-resources**. Kotlin chose a library function (`use`) plus lambdas instead of dedicated syntax, which is a recurring theme in the stdlib: runtime concepts are mapped onto inline functions rather than new keywords.
- What happens if both the block and close() throw?The block's exception propagates; the close() exception is attached to it via addSuppressed and retrievable from Throwable.suppressed.
- Can use return a value?Yes — use returns whatever the lambda returns, so you can compute and return a result directly.
Like a self-locking door: you walk through, do your thing, and it locks behind you no matter how you leave.
saying these in an interview costs you the question
- Claiming use only works on files
- Saying you still need a manual finally with use
- Thinking close() runs only on success, not on exception
- Believing the close exception overwrites/hides the original error
- Not knowing use returns the lambda result