## Records vs Tuples

Mun supports two types of structures: record structs and tuple structs. A record `struct` definition specifies both the name and type of each piece of data, allowing you to retrieve the field by name. For example, Listing 4-1 shows a record `struct` that stores a 2-dimensional vector.

``````pub struct Vector2 {
x: f32,
y: f32,
}
``````

Listing 4-1: A record `struct` definition for a 2D vector

In contrast, tuple `struct` definitions omit field names; only specifying the field types. Using a tuple `struct` makes sense when you want to associate a name with a tuple or distinguish it from other tuples' types, but naming each field would be redundant. Listing 4-2 depicts a tuple `struct` that stores a 3-dimensional vector.

``````pub struct Vector3(f32, f32, f32)
``````

Listing 4-2: A tuple `struct` definition for a 3D vector

### Create a Struct Instance

To use a record `struct`, we create an instance of that struct by stating the name of the `struct` and then add curly braces containing `key: value` pairs for each of its fields. The keys have to correspond to the field names in the `struct` definition, but can be provided in any order. Let's create an instance of our `Vector2`, as illustrated in Listing 4-3.

``````pub struct Vector2 {
x: f32,
y: f32,
}
let xy = Vector2 {
x: 1.0,
y: -1.0,
};
``````

Listing 4-3: Creating a `Vector2` instance

To create an instance of a tuple `struct`, you only need to state the name of the `struct` and specify a comma-separated list of values between round brackets - as shown in Listing 4-4. As values are not linked to field names, they have to appear in the order specified by the `struct` definition.

``````pub struct Vector3(f32, f32, f32)
let xyz = Vector3(-1.0, 0.0, 1.0);
``````

Listing 4-4: Creating a `Vector3` instance

#### Field Init Shorthand

It often makes sense to name function variables the same as the fields of a record `struct`. Instead of having to repeat the `x` and `y` field names, the field init shorthand syntax demonstrated in Listing 4-5 allows you to avoid repetition.

``````pub struct Vector2 {
x: f32,
y: f32,
}
pub fn vector2_new(x: f32, y: f32) -> Vector2 {
Vector2 { x, y }
}
``````

Listing 4-5: Creating a `Vector2` instance using the field init shorthand syntax

### Access Struct Fields

To access a record's fields, we use the dot notation: `vector.x`. The dot notation can be used both to retrieve and to assign a value to the record's field, as shown in Listing 4-6. As you can see, the record's name is used to indicate that the function expects two `Vector2` instances as function arguments and returns a `Vector2` instance as result.

``````pub struct Vector2 {
x: f32,
y: f32,
}
pub fn vector2_add(lhs: Vector2, rhs: Vector2) -> Vector2 {
lhs.x += rhs.x;
lhs.y += rhs.y;
lhs
}
``````

Listing 4-6: Using `Vector2` instances' fields to calculate their addition

A tuple `struct` doesn't have field names, but instead accesses fields using indices - starting from zero - corresponding to a field's position within the struct definition (see Listing 4-7).

``````pub struct Vector3(f32, f32, f32)
pub fn vector3_add(lhs: Vector3, rhs: Vector3) -> Vector3 {
lhs.0 += rhs.0;
lhs.1 += rhs.1;
lhs.2 += rhs.2;
lhs
}
``````

Listing 4-7: Using `Vector3` instances' fields to calculate their addition

### Unit Struct

Sometimes it can be useful to define a `struct` without any fields. These so-called unit structs are defined using the `struct` keyword and a name, as shown in Listing 4-8.

``````pub struct Unit;
``````

Listing 4-8: A unit `struct` definition.