Types

Let's take a moment to discuss the different types we've encountered:

  • The empty unit type () is used when a function or expression does not return a value. It's essentially a placeholder indicating the absence of a meaningful value.
  • String slices &str are references to a portion of a string. They allow you to work with parts of a string without needing to own the entire string, making them efficient and flexible.
  • Signed 32-bit integers i32 are integers that can store both positive and negative values within a specific range. They are commonly used for numerical operations where the size of the number is known and fits within the 32-bit limit.

Understanding these types will help us write more efficient and effective Rust code as we continue to build our grep program.

String Slice str

The most interesting type is probably str. str is a primitive string type in Rust, and it's usually seen in its borrowed1 form &str.

You can think of a string slice as an object with two components:

fieldvalue
ptraddress
lenunsigned integer

Imagine a block of memory starting at address 0x10 containing the bytes for the string literal "rust". This block of memory would store the individual bytes representing each character in the string. In this case, the memory would contain the bytes for 'r', 'u', 's', and 't', sequentially stored starting from address 0x10.

This visualization helps in understanding how string literals are stored and accessed in memory:

0x100x110x120x13
rust

When we bind the string literal "rust" to the variable language:

let language = "rust";

The memory would look like:

fieldvalue
ptr0x10
len4

Primitive Types

Here are some additional primitive types in Rust:

typedescription
arrayA fixed-size array, denoted [T; N], for the element type, T, and the non-negative compile-time constant size, N.
boolThe boolean type.
charA character type.
f32A 32-bit floating-point type (specifically, the “binary32” type defined in IEEE 754-2008).
f64A 64-bit floating-point type (specifically, the “binary64” type defined in IEEE 754-2008).
i8The 8-bit signed integer type.
i16The 16-bit signed integer type.
i32The 32-bit signed integer type.
i64The 64-bit signed integer type.
i128The 128-bit signed integer type.
isizeThe pointer-sized signed integer type.
strString slices.
u8The 8-bit unsigned integer type.
u16The 16-bit unsigned integer type.
u32The 32-bit unsigned integer type.
u64The 64-bit unsigned integer type.
u128The 128-bit unsigned integer type.
usizeThe pointer-sized unsigned integer type.

User-defined Types

In addition to the primitive types, Rust supports user-defined types. We'll cover them in more detail as we build our grep program. But to satisfy your curiosity, some of the user-defined types include:

typedescription
structA heterogeneous product of other types, called the fields of the type.2
enumAn enumerated type is a nominal, heterogeneous disjoint union type, denoted by the name of an enum item.3
unionA union type is a nominal, heterogeneous C-like union, denoted by the name of a union item.

These user-defined types allow for more complex and expressive code, enabling you to model real-world concepts more effectively. We'll explore these in greater depth as we progress through our project.


1

We'll explore what borrowing means during the course.

2

struct types are analogous to struct types in C.

3

The enum type is analogous to a data constructor declaration in Haskell, or a pick ADT in Limbo.