Roby Cigar
Roby Cigar

Reputation: 948

What is a real world example of using a unit struct?

I read these docs about structs, but I don't understand about unit structs. It says:

Unit structs are most commonly used as marker. They have a size of zero bytes, but unlike empty enums they can be instantiated, making them isomorphic to the unit type (). Unit structs are useful when you need to implement a trait on something, but don’t need to store any data inside it.

they only give this piece of code as an example:

struct Unit;

What is a real world example of using a unit struct?

Upvotes: 16

Views: 7775

Answers (2)

kmdreko
kmdreko

Reputation: 60272

In addition to providing a basis for stateless trait implementations, you may also see unit structs created simply to serve as a marker (as mentioned in the quote) to be used in some other structure. Some examples:

  • In std::marker, there are PhantomData and PhantomPinned which are used to augment other types in concert with the compiler for variance, auto-generated traits, or other behavior. These in particular are special cases and not really a usable pattern outside the standard library.

  • You can see marker types used in the typestate pattern. Like Rocket<P> in Rocket v0.5. It uses P as simply an indicator of what "pahse" the application is in and provides methods only with specific phases (like can't configure after it is started). Technically Build/Ingite/Orbit are empty structs and not unit structs, but that distinction isn't meaningful here.

  • You can also see marker types used similarly for defining Format options in the tracing-subscriber crate. The Compact type (a unit struct) is used in conjunction with it to provide different methods and behavior that are not tied to itself directly (Compact implements no traits, and has no methods; the specialization comes from Format<Compact, T> implementing FormatEvent).

Upvotes: 5

Shepmaster
Shepmaster

Reputation: 431299

Standard library

Global

The global memory allocator, Global, is a unit struct:

pub struct Global;

It has no state of its own (because the state is global), but it implements traits like Allocator.

std::fmt::Error

The error for string formatting, std::fmt::Error, is a unit struct:

pub struct Error;

It has no state of its own, but it implements traits like Error.

RangeFull

The type for the .. operator, RangeFull, is a unit struct:

pub struct RangeFull;

It has no state of its own, but it implements traits like RangeBounds.

Crates

chrono::Utc

The Utc timezone is a unit struct:

pub struct Utc;

It has no state of its own, but it implements traits like TimeZone and is thus usable as a generic argument to Date and DateTime.

Upvotes: 20

Related Questions