Rust, Software Development

Using #[non_exhaustive] for Non-exhaustive Structs

Non-exhaustive 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 expression 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 just disallow struct expressions? We could use #[non_exhaustive]!

Crate-Level-Only Structs

There is 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.

Crate mycrate lib.rs

This crate has the 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 structs, which in this case, is just Person.

Crate myapp

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

Output:

Tested with Rust 1.40.0.

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