Skip to Content

Using

using confines a resource’s lifetime to a block scope: you hold the resource on entry, and leaving the block automatically calls Dispose. It fits resources that need explicit release — file handles, database connections, transactions.

The Resource Contract: Disposable

The type hosted by using must implement the Disposable protocol, which means providing a parameterless Dispose method. Bring in the protocol with import System.Disposable;:

import System.Disposable; class FileHandle impl Disposable { public var name: string; init(n: string) { name = n; print("open", name); } public func Dispose() { print("close", name); } }

Three Forms

using val r = new Resource(); { } // declare and bind (no semicolon; the block follows immediately) using name = expr { } // resource binding using expr { } // expression resource

The declaration form’s binding is visible inside the block and does not exist outside it. Write constructor arguments directly in new; do not use object initializers: the initializer’s { would be confused with using’s body block.

Nesting and Dispose Order

A using block disposes immediately when it ends; nested blocks dispose in reverse entry order — the last one opened closes first:

using val outer = new FileHandle("database") { using val inner = new FileHandle("transaction") { print("using", outer.name, "and", inner.name); } print("transaction closed, database still open"); } print("all closed");
open database open transaction using database and transaction close transaction transaction closed, database still open close database all closed

The transaction closes the moment the inner block ends, while the database handle stays open until the outer block ends. This order is isomorphic to the last-in-first-out of defer.

The Expression Form

Use the expression form when the resource needs no name: the block cannot reach a reference; the point is purely “paired entry and exit”:

using new FileHandle("temp") { print("one-shot resource"); } print("continue outside the block");
open temp one-shot resource close temp continue outside the block

Notes

  • The using body must be a block; a standalone using r; is a syntax error.
  • Dispose is an ordinary method: a type implementing Disposable can also be disposed by hand, but with using there is no need to manage it manually.
  • The deinit destructor is only called as a supplement when a using exits (in reverse base-class order); ordinary block exits do not trigger it, and the scripting version of the language makes no promise about destructor timing.
  • A protocol itself can also serve as the resource type (using val p: P = new R()); Dispose dispatches through the protocol slot to the concrete type, provided the protocol declaration chain carries the Dispose signature.
Last updated on October 11, 2026