Learn Rust Programming Language in One Article

Learn Rust Programming Language in One Article

Rust is a multi-paradigm, general-purpose programming language that emphasizes performance, type safety, and concurrency. It enforces memory safety

ยท

6 min read

Table of contents

Variable

Rust, a variable is a name given to a memory location that holds a value. Unlike some other programming languages, Rust has a strong static type system, which means that variables must have a known type at compile-time. This enables Rust to provide safety guarantees and avoid certain types of bugs commonly found in dynamically-typed languages.

To declare a variable in Rust, you use the let keyword followed by the variable name and an optional type annotation. Here's the basic syntax:

let variable_name: data_type = value;

Let's break down each part:

  1. let: The keyword used to introduce a new variable.

  2. variable_name: This is the name you give to the variable. It must follow Rust's naming conventions (snake_case is the preferred style).

  3. data_type (Optional): The data type of the variable. If you don't explicitly specify a type, Rust will infer it based on the assigned value. However, in some cases, you might want to provide an explicit type to clarify your intentions or to handle situations where the type of inference might not work as expected.

  4. value: The initial value assigned to the variable. The assigned value must be compatible with the variable's data type.

Here are a few examples:

// Variable with explicit type annotation
let number: i32 = 42;

// Variable with type inference
let name = "John";

// Mutable variable (the 'mut' keyword allows reassignment)
let mut counter: u8 = 0;
counter = 10;

// Variable shadowing (redefining a variable with the same name)
let age: u32 = 30;
let age: u64 = 30; // This shadows the previous 'age' variable, and it's now of type u64.

Rust has the concept of "mutability," meaning you can make a variable mutable by using the mut keyword. Mutable variables can have their values changed after they are initialized. However, by default, variables are immutable, which ensures that their values cannot be changed once assigned, providing a level of safety.

let immutable_variable = 5;
immutable_variable = 10; // This will result in a compilation error since the variable is immutable.

If you want to modify the value of a variable, you need to use the mut keyword when declaring the variable:

let mut mutable_variable = 5;
mutable_variable = 10; // This is allowed since the variable is mutable.

Variable shadowing is another important concept in Rust. It allows you to redefine a variable with the same name in the same scope, effectively hiding the previous variable. Shadowing is different from mutability, as it allows you to change the type and value of the variable.

Rust's strong type system, immutability by default, and focus on safety make it a powerful language for systems programming, where predictability and reliability are crucial.


Data Type

Let's explore the data types you mentioned in Rust:

Scaler Type

  1. Integers: Integers represent whole numbers without fractional parts. Rust provides signed and unsigned integers of different sizes. The signed integers can represent both positive and negative numbers, while unsigned integers can only represent positive numbers (or zero).

    Some common integer types in Rust include:

    • i8: 8-bit signed integer (-128 to 127)

    • i16: 16-bit signed integer (-32,768 to 32,767)

    • i32: 32-bit signed integer (-2^31 to 2^31 - 1)

    • i64: 64-bit signed integer (-2^63 to 2^63 - 1)

    • u8: 8-bit unsigned integer (0 to 255)

    • u16: 16-bit unsigned integer (0 to 65,535)

    • u32: 32-bit unsigned integer (0 to 4,294,967,295)

    • u64: 64-bit unsigned integer (0 to 18,446,744,073,709,551,615)

Example:

    let a: i32 = 234;
    let b: u64 = 9876543210;
  1. Floating-point Numbers: Floating-point numbers represent real numbers and include both fractional and non-fractional parts. Rust has two types for representing floating-point numbers: f32 (single-precision) and f64 (double-precision).

    Example:

     let pi: f64 = 3.141592653589793;
     let gravity: f32 = 9.81;
    
  2. Booleans: Booleans represent logical values, and there are two possible values in Rust: true and false. Booleans are used in conditional expressions and control flow statements to make decisions.

    Example:

     let is_raining: bool = true;
     let is_sunny = false; // Type inference will determine the type as bool.
    
  3. Characters: Characters in Rust are represented using single quotes and are used to store individual Unicode characters. Unlike some other programming languages, where characters are represented using their ASCII values, Rust's char type represents a single Unicode scalar value.

    Example:

     let letter_a: char = 'A';
     let smiley_face = '๐Ÿ˜Š'; // Unicode character representing a smiley face.
    

In Rust, you can also use compound data types like arrays, tuples, and structs to group multiple values together. These data types allow you to create more complex data structures and express relationships between different pieces of data in your program.

Compound Type

  1. Array Type: An array is a fixed-size collection of elements of the same data type. Arrays in Rust have a fixed length, which means you must specify the number of elements the array will hold at the time of declaration. Once defined, the size of an array cannot be changed during runtime.

    The syntax for declaring an array in Rust is as follows:

     let array_name: [data_type; size] = [element1, element2, ..., elementN];
    
    • array_name: The name you give to the array variable.

    • data_type: The data type of the elements in the array. All elements in the array must have the same data type.

    • size: The number of elements the array can hold. It must be a non-negative integer.

    • [element1, element2, ..., elementN]: The values of the elements in the array. The number of elements provided in the array initializer must match the specified size.

Example:

    let numbers: [i32; 6] = [2, 3, 4, 32, 4, 5];

In this example, we have declared an array called numbers, which can hold 6 elements of type i32 (32-bit signed integers). The array is initialized with the provided values.

Accessing elements in an array is done using square brackets and the index of the element (indexes start at 0):

    let first_element = numbers[0]; // Accessing the first element (2)
    let third_element = numbers[2]; // Accessing the third element (4)

Be cautious not to access elements beyond the array's bounds, as it can lead to undefined behavior or runtime errors.

  1. Tuple Type: A tuple is an ordered, fixed-size collection of elements of potentially different data types. Tuples are useful when you want to group multiple values together without creating a separate data structure. Unlike arrays, tuples can hold elements of different types.

    The syntax for declaring a tuple in Rust is as follows:

     let tuple_name: (data_type1, data_type2, ..., data_typeN) = (value1, value2, ..., valueN);
    
    • tuple_name: The name you give to the tuple variable.

    • data_type1, data_type2, ..., data_typeN: The data types of each element in the tuple.

    • (value1, value2, ..., valueN): The values of the elements in the tuple. The number and types of values must match the specified data types.

Example:

    let tup: (i32, f64, u8, char) = (500, 4.5, 1, 'g');

In this example, we have declared a tuple named tup, containing elements of different types: an i32, an f64, a u8, and a char.

You can access elements in a tuple using pattern matching or by using the dot followed by the index (indexes start at 0):

    let first_element = tup.0; // Accessing the first element (500)
    let second_element = tup.1; // Accessing the second element (4.5)
    let third_element = tup.2; // Accessing the third element (1)
    let fourth_element = tup.3; // Accessing the fourth element ('g')

Tuple destructuring can also be used to extract individual elements from a tuple:

    let (x, y, z, ch) = tup;

Now x, y, z, and ch will hold the corresponding values from the tup tuple.

Tuples are particularly useful when you need to return multiple values from a function, and their types are known at the time of declaration.

ย