Skip to content
This repository has been archived by the owner on Dec 21, 2019. It is now read-only.

tazjin/defer.rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

defer in Rust

After a Hacker News discussion about implementing Go's defer keyword in C++, I stumbled upon this comment and more specifically this response to it by "Occivink":

There's plenty of one-time cases where you don't want to declare an entire class but still enjoy scope-based functions.

Specificall the "don't want to declare an entire class" suggests that languages like C++ have high friction for explaining your desired invariant (cleanup is run when $thing is destroyed) to the compiler.

It seems like most languages either hand-wave this away (cough Java cough) or use what seems like a workaround (defer).

Rust has the so-called Drop trait, which is a typeclass that contains a single method with no return value that is run when a variable is dropped (i.e. goes out of scope).

This works fine for most general cases - i.e. closing file handlers - but can get complicated if other use-cases of defer are considered:

  • returning an error-value by mutating a reference in the enclosing scope (oh boy)
  • deferring a decision about when/whether to run cleanup to the caller

While thinking about how to do this with the Drop trait I realised that defer can actually be trivially implemented in Rust, using Drop.

A simple implementation of defer can be seen in defer.rs, an implementation using shared mutable state for error returns is in the file defer-with-error.rs and an implementation that allows cleanup to be cancelled (don't actually do this, it leaks a pointer) is in undefer.rs.

Whether any of this is actually useful is not up to me to decide. I haven't actually had a real-life need for this.

You can run the examples with cargo run --example defer, etc.

Notes

  • Drop is not guaranteed to run in case of panics or program aborts, if you need support for that check out scopeguard
  • undefer could be implemented safely by, for example, carrying a boolean that by default causes execution to happen but can be flipped to disable it

Further reading:

About

Go's defer keyword, in Rust.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published