Rust, Software Development

Using #[non_exhaustive] for Non-exhaustive Rust Structs

Non-exhaustive Rust structs will future-proof our codes by preventing client codes from using Struct expressions. We use Struct expressions to instantiate structs, and they’re JSON-like expressions in appearance with all fields present. When we update a struct with a new field,  all expressions must be updated to include that field.

The non_exhaustive attribute indicates that a type or variant may have more fields or variants added in the future. It can be applied to structs, enums, and enum variants.

For example, we have a struct Pet with two initial fields – name and age.

We can instantiate it using a struct expression as follows.

The codes work until we add a new field owner to the Struct.

Wouldn’t it be better if we could disallow struct expressions? We could use #[non_exhaustive]!

Non-exhaustive Struts are Crate-Level Only

One important thing to note about #[non_exhaustive]; it only works at the crate level.

Using #[non_exhaustive] for Non-exhaustive Structs

Using #[non_exhaustive] for Non-exhaustive Structs

How, then, do we instantiate structs? Through factory functions provided by the crate with non-exhaustive structs.

Non-exhaustive Structs In Crate mycrate lib.rs

This crate has non-exhaustive structs. These are just structs marked with #[non_exhaustive]. The following codes have a struct with two public factory functions to instantiate it in the client codes. They are using #[non_exhaustive] on a struct, which in this case, is just Person.

When our Struct is non-exhaustive, we restrict the client codes to use the factory functions we defined for the Struct. Therefore, the only way the client codes can instantiate our Struct is via those functions.

Crate myapp that Uses Non-Exhaustive Rust Strut

This crate uses mycrate that has those non-exhaustive structs. Any attempts to use struct expressions to instantiate those structs will fail the building process.

Cargo.toml

main.rs

With our Struct, the following codes show the only way we can instantiate our Person struct. The Rust codes use factory functions we defined in the crate mycrate.

Output:

Tested with Rust 1.64.0.

The non-exhaustive attribute can also make Rust enum non-exhaustive. However, it has slightly different semantics than the Non-exhaustive rust Structs.

Got comments or suggestions? We disabled the comments on this site to fight off spammers, but you can still contact us via our Facebook page!.


You Might Also Like