Understanding Rust’s Data Types

A Comprehensive Guide with Examples

Raunak
Rustaceans
Published in
4 min readApr 15, 2024

--

Rust is known for its strong emphasis on memory safety, concurrency, and performance. Central to Rust’s design philosophy is its rich set of data types, which enable developers to write efficient and safe code. In this article, we’ll discuss Rust’s fundamental data types along with illustrative examples to deepen your understanding.

  1. Primitive Data Types

Rust provides several primitive data types, including integers, floating-point numbers, booleans, characters, and the unit type ().

  • Integers

Rust supports signed and unsigned integers of various sizes (8, 16, 32, 64, and arch), and selecting an appropriate size is important because it allows precise control over memory usage and arithmetic operations.

How you select the appropriate int size depends on the domain in which rust is going to be executed, Check out this link to learn more about determining appropriate int size

For example

let numb :i32 = 123;
  • Floating-Point Numbers

Rust offers both single (f32) and double (f64) precision floating-point numbers. These are useful for representing decimal values.

let flt:f32 = 3.14;
  • Booleans

Booleans represent true or false values, which are essential for control flow and logical operations.

  • Characters

Rust’s char type represents a Unicode scalar value, allowing for internationalization and support for various scripts.

let heart_emoji: char = '❤';
  • Unit Type

The unit type () is a special type with only one value, also denoted as an empty tuple. It's often used to indicate that a function does not return a meaningful value.

fn print_hello() { println!("Hello, world!"); }
  1. Compound Data Types

Rust also provides compound data types to aggregate multiple values into one.

  • Arrays

Arrays in Rust have a fixed size and hold elements of the same type.

let numbers: [i32; 5] = [1, 2, 3, 4, 5]; // "i32 determines the types."
// 5 determines the size
// array are homogenous i.e they only 1 type of data.
  • Vectors

Vectors are very similar to arrays, but a great thing is that their sizes can be changed, i.e., more items can be pushed and existing items can be pulled.

The other time when vector is much worse is when you use a vector of vector vs a multidimensional array because each vector is allocated separately and lies all around memory which is not good for caching.

let numberVec: Vec::new();
numberVec.push(1);
numberVec.push(2);

Arrays and vectors both store data in a linear contiguous array, where accessing or iterating is both an O(1) operation, so there’s no difference in performance. The only case when vectors are slower is probably for some small lists because arrays are stored on the stack in the current stack frame hence, their data is highly probably already loaded to the CPU cache. Vector OTOH stores data on the heap so data will not be available in cache before they’re first accessed

Vector also has one more level of redirection because you need to load the address of the array first so the first memory access may also be slower, but that’s just negligible

The other time when vector is much worse is when you use a vector of vector vs a multidimensional array because each vector is allocated separately and lies all around memory, which is not good for caching.

  • Tuples

Tuples are collections of values of different types. They are useful when you want to combine a fixed number of heterogeneous data items.

let mut person: (&str, i32, bool) = ("Alice", 30, "UK");
println!("Person details are {:?}", person); // original details
person.1 = "35";
person.2 = "USA";
println!("Changed tuple = {:?}", person); // changed details


// tuples can be written dynamically as well
let mut mountain_heights = ("Everest", 8848, "Fishtail", 6993);
// here type definition is not given, directly values are combined into tuple.
println!("Original tuple = {:?}", mountain_heights);
  1. Custom Data Types

Rust enables developers to define their own data types using structs and enums.

  • Structs

Structs allow you to create custom data structures by grouping related data fields.

struct Point {
x: f64,
y: f64
};
let origin = Point { x: 0.0, y: 0.0 };
  • Enums

Enums allow you to define a type by enumerating its possible variants.

enum Direction {     
Up,
Down,
Left,
Right,
};

let current_direction = Direction::Right;

In conclusion, Rust’s diverse set of data types equips developers with powerful tools to build efficient and safe software. By understanding and leveraging these data types effectively, developers can write robust and reliable Rust code for a wide range of applications.

--

--