When looking up part of Rust's syntax or a particular feature, it's always a good idea to check The Rust Reference. For example, the struct
page shows the syntax in a pseudo-BNF form and mentions the different ways they can be declared.
A struct is a nominal struct type defined with the keyword struct
.
An example of a struct
item and its use:
struct Point {x: i32, y: i32}
let p = Point {x: 10, y: 11};
let px: i32 = p.x;
A tuple struct is a nominal tuple type, also defined with the keyword struct
. For example:
struct Point(i32, i32);
let p = Point(10, 11);
let px: i32 = match p { Point(x, _) => x };
A unit-like struct is a struct without any fields, defined by leaving off the list of fields entirely. Such a struct implicitly defines a constant of its type with the same name. For example:
struct Cookie;
let c = [Cookie, Cookie {}, Cookie, Cookie {}];
is equivalent to
struct Cookie {}
const Cookie: Cookie = Cookie {};
let c = [Cookie, Cookie {}, Cookie, Cookie {}];
The precise memory layout of a struct is not specified. One can specify a particular layout using the repr
attribute.
As an aside, what you are seeing is often referred to as the Newtype Pattern.
This is where you'll take an existing type and wrap it in your own type to either add application-specific methods, provide encapsulation, or mediate access (e.g. you have invariants that must be upheld, and letting people access the item directly could violate them).
Depending on the scenario you may also make the field pub
so users have access to the inner type. Implementing Deref
may also make sense if a pointer to your newtype should also be considered as a pointer to the inner type, although using this to implement a poor man's version of inheritance is frowned upon and will often lead to frustration because you are using a tool for something it's not intended for (Deref
is for implementing something that behaves like a pointer, not is-a relationships).