Defer in D Programming Language

Our example demonstrates the use of scope(exit) in D, which is similar to the defer keyword in other languages. It’s used to ensure that a function call is performed later in a program’s execution, usually for purposes of cleanup.

import std.stdio;
import std.file;

void main()
{
    // Immediately after getting a file object with
    // createFile, we use scope(exit) to ensure the closing
    // of that file. This will be executed at the end
    // of the enclosing function (main), after
    // writeFile has finished.
    auto f = createFile("/tmp/defer.txt");
    scope(exit) closeFile(f);
    writeFile(f);
}

File createFile(string p)
{
    writeln("creating");
    auto f = File(p, "w");
    return f;
}

void writeFile(File f)
{
    writeln("writing");
    f.writeln("data");
}

// It's important to check for errors when closing a
// file, even in a scope(exit) block.
void closeFile(File f)
{
    writeln("closing");
    f.close();
}

Running the program confirms that the file is closed after being written.

$ rdmd defer.d
creating
writing
closing

In this D version:

  1. We use scope(exit) instead of defer. This ensures that the closeFile function is called when the current scope (in this case, main) exits.

  2. We use D’s File type instead of Go’s *os.File.

  3. Error handling is slightly different in D. Instead of using panic, D would typically use exceptions. However, for simplicity, we’ve omitted explicit error handling in this example.

  4. The createFile function returns a File object directly, rather than a pointer.

  5. In D, we use auto for type inference where applicable.

  6. We use writeln from std.stdio instead of fmt.Println.

This example demonstrates how D’s scope(exit) can be used to ensure cleanup operations are performed, similar to Go’s defer.