DEV Community

Cover image for Introduction to Common Programming Concepts in Rust
Son DotCom 🥑💙
Son DotCom 🥑💙

Posted on

Introduction to Common Programming Concepts in Rust

In this article, we'll explore some fundamental programming concepts present in Rust, such as variables, conditions, and basic types. To make the most out of this article, it's recommended to have some prior experience with at least one programming language like Python, JavaScript, or Java.

What is Rust

Rust is a statically typed programming language designed for performance and safety. Originally developed at Mozilla, it caters to system-level programmers who work with low-level byte tweaking code. You can learn more about the history of Rust here.

Installation

As this article primarily focuses on teaching programming concepts, we won't delve deep into installation. If you wish to install Rust globally on your computer, you can follow the instructions here. Alternatively, you can code along with the article using the Rust Playground app.

Let's dive right in and start exploring Rust!

Variables

Declaring variables in Rust is straightforward. We use the let keyword to do so.

   let even_number = 2;
Enter fullscreen mode Exit fullscreen mode

This is similar to the let keyword in JavaScript, but Rust treats it differently. By default, variables in Rust are immutable, meaning you can't change the value assigned to a variable.

code representing rust variable declaration without mut keyword

As shown above, our code fails because we are unable to change the value of our variable even_number. To change the value of a variable, we must add the mut keyword, which stands for "mutate."

 let mut even_number = 2;
Enter fullscreen mode Exit fullscreen mode

code representing rust variable declaration with mut keyword

Now, our code runs fine and prints an output (Note: ignore the warning signs for now, they only indicate that we haven't used the even_number variable).

A variable in Rust can only have one type, which can either be explicitly assigned or inferred by the Rust compiler. Unlike JavaScript, once a type is assigned to a variable in Rust, it cannot be changed.

 let mut even_number = 2;
// This will not compile
 even_number = true;
Enter fullscreen mode Exit fullscreen mode

image showing we can change variable types in rust

As seen above, the Rust compiler throws an error for "mismatched types." It expects the even_number variable to always be an integer but got a boolean type.

Basic Types

Boolean

A Boolean type is a type that can have only two values: true or false. To declare a boolean in Rust, we use the bool keyword.

let is_valid: bool = true; 
Enter fullscreen mode Exit fullscreen mode

By default, variables declared as bool are automatically set to false.

let is_updated: bool; // will be false 
Enter fullscreen mode Exit fullscreen mode

Boolean types are mainly used in conditionals, such as if and else statements, where you can check if a variable is true and proceed accordingly.

Integers

Integers in Rust are numbers without decimal points. There are two types of integers in Rust: signed and unsigned integers.

Signed Integers

Signed integers can be positive or negative. Examples include: 20, -20, 34, -34, etc. Signed integers are represented by adding an i at the start of the integer range.

  let count: i64 = 1501
Enter fullscreen mode Exit fullscreen mode

Unsigned Integers

Unsigned integers are only positive integers. Examples include: 20, 34, 42, 382728289, etc. Unsigned integers are represented by adding a u at the start of the integer range.

  let age: u8 = 54
Enter fullscreen mode Exit fullscreen mode

The integer type specifies the length of data that the variable can hold.

For Signed:

Length Signed Range
8-bit i8 -128 to 127
16-bit i16 -32,768 to 32,767
32-bit i32 -2.147e9 to 2.147e9
64-bit i64 -9.223e18 to 9.223e18
128-bit i28 -1.701e38 to 1.701e38

For Unsigned:

Length UnSigned Range
8-bit u8 0 to 255
16-bit u16 0 to 65,535
32-bit u32 0 to 4.295e9
64-bit u64 0 to 1.844e19
128-bit u28 0 to 3.403e38

If we use an integer type and assign a value below or above the range of that type, Rust will panic.

Example:

   // this will not compile 
   let counter: i8 = 128;
Enter fullscreen mode Exit fullscreen mode

Floats

Floats are numbers with decimal points. All float types in Rust are signed. There are two types of floats in Rust: f32 and f64.

Example:

   let amount: f32 = 20.50; 
Enter fullscreen mode Exit fullscreen mode

Character

This type is similar to character in other programming languages and is represented with the char keyword.

Example:

  let alphabet: char = 'a';
Enter fullscreen mode Exit fullscreen mode

Notice that the value of the char type must be enclosed in single quotes.

Compound Types

Arrays

Arrays are used to group data of the same type together. Unlike arrays in JavaScript, Rust arrays are not dynamic. Rust arrays are stored on the stack, so their size and length must be known during initialization.

To declare an array, use the syntax [type; size], where type is the type of data to store, and size is the number of elements in the array.

Example:

   let students_age: [u8; 5] = [10, 12, 9, 11, 10];
Enter fullscreen mode Exit fullscreen mode

Values in an array must be of the same type. You can't have a char inside an array of numbers like you could in JavaScript.

Example:

example code showing you can't add multiple types to a single array in Rust

The above example fails because the char type was included in the list.
Notice that we didn't explicitly add the array type because Rust can infer it from the provided data.

Accessing and Updating Arrays

Accessing an array element in Rust is similar to other programming languages: we use the element's index.

Example:

fn main() {
   let numbers = [3,2,3,5,7,8,9]; 
   println!("{}", numbers[0]); // 3
   println!("{}", numbers[4]); // 7
}
Enter fullscreen mode Exit fullscreen mode

To update or mutate an array, we must use the mut keyword.

Example:

fn main() {
   let mut numbers = [3,2,3,5,7,8,9]; 
   numbers[0] = 1; 
   println!("{:?}", numbers) // [1,2,3,5,7,8,9]; 
}
Enter fullscreen mode Exit fullscreen mode

As shown from the above the first number in the array was changed from 3 to 1.
NB: The :? is a debug trait, you shouldn't worry about that now but you will need to include that to display the array of numbers.

Vectors

Vectors are similar to arrays but are dynamic, meaning their sizes can change. They are stored on the heap rather than the stack. To represent a vector type, use Vec<T> and initialize it with vec![...].

Example:

   let counter: Vec<i8> = vec![4, -5, 7]; 
Enter fullscreen mode Exit fullscreen mode

From the above we declare a vector of type i8 with three values.

We can also declare a vector with zero initial values using: Vec::new()

Example:

   let mut current_counts: Vec<i8> = Vec::new();
   println!("{:?}", current_counts); // []
Enter fullscreen mode Exit fullscreen mode

To add more values to a vector, use the .push method.

Example

  let mut current_counts: Vec<i8> = Vec::new();
   current_counts.push(5);
   println!("{:?}", current_counts) // [5]
Enter fullscreen mode Exit fullscreen mode

To remove items from the vector, use the .pop method.

Example:

   let mut counter: Vec<i8> = vec![4, -5, 7]; 
   counter.pop(); 
   counter.pop(); 
   println!("{:?}", counter) // [4]
Enter fullscreen mode Exit fullscreen mode

From the above we call the pop method twice which removed two elements from the vector.

Also just link arrays we also use the index of elements to access those elements in the vector.

Example:

   let counter: Vec<i8> = vec![4, -5, 7]; 
   println!("{}", counter[1] ); // -5
Enter fullscreen mode Exit fullscreen mode

Conditions

Rust conditionals work similarly to other programming languages. To conditionally run a block of code, use the if else expression.

Example

fn main() {
   let count = 2;
    if count > 2 {
        println!("Count is greater than 2");
    } else {
        println!("Count is less than 2");
    }
}
Enter fullscreen mode Exit fullscreen mode

The conditions must always evaluate to a bool type. The code below will not compile:

   let count = 2;
   // This will fail 
    if count {
        println!("Count is greater than 2");
    } else {
        println!("Count is less than 2");
    }
Enter fullscreen mode Exit fullscreen mode

count is an integer type, not a bool type. Unlike JavaScript, Rust does not implicitly typecast.

Loops

Rust offers three kinds of loops: for, while, and loop.

For loop

The for loop in Rust is similar to for-in loops in JavaScript. It is used primarily with arrays and allows you to loop over each element.

Example:

fn main() {
   let numbers = [3,2,3,5,7,8,9]; 

    for num in numbers {
        println!("the number is: {num}");
    }
}
Enter fullscreen mode Exit fullscreen mode

You can also loop over a range with the Rust for loop.

Example:

fn main() {
    for num in 0..10 {
        println!("the number is: {num}");
    }
}
Enter fullscreen mode Exit fullscreen mode

While loop

While loops execute a block of code repeatedly as long as a condition is true. The loop breaks when the condition becomes false.

Example:

fn main() {
    let numbers = [3,2,3,5,7,8,9]; 
    let mut cal = 0;
    let mut index = 0;

    while cal <= 20 {
        println!("the current calculated value is: {}", cal);
        cal += numbers[index];
        index += 1;
    }
}
Enter fullscreen mode Exit fullscreen mode

From the above the loop will continue to until the variable cal is greater than 20 then it stops.

loop

The loop executes a block of code infinitely until you manually stop it using the break keyword.

Example:

fn main() {
   let mut counter = 0;

    loop {
        counter += 1;
        println!("The counter is currently {counter}");
        if counter == 10 {
           counter = counter * 2;
            break;
        }
    };

    println!("Total counter is {counter}");
}
Enter fullscreen mode Exit fullscreen mode

Function

Declaring a function in Rust is similar to other programming languages. So far, we have seen the main function, which serves as the entry point that Rust looks for when running our code.

We can create our own functions with different names and use them in the main function.

fn main() {
  let result = addition(20, 20);
  println!("result: {}", result);

 }

 fn addition(num1: i8, num2: i8) -> i8 {
      num1 + num2
 }
Enter fullscreen mode Exit fullscreen mode

In the above example, we created a function named addition with two arguments, num1 and num2, both of type i8, and a return type -> i8.

Notice that within the addition function, we didn't explicitly add the return keyword. This is valid because Rust will implicitly return any line within the function that doesn't end with a semicolon

Exercise

Now that we've covered a lot of ground, it's time to test your skills with an exercise:

Write a program that uses println! to print all the numbers from 1 to 100, with two exceptions. For numbers divisible by 3, print "Fizz" instead of the number, and for numbers divisible by 5 (but not 3), print "Buzz" instead. For numbers divisible by both 3 and 5, print "FizzBuzz".

In conclusion, this article provided an introductory overview of common programming concepts in Rust. We explored variables, conditions, basic types, and compound types like arrays and vectors. Additionally, we covered loops, functions, and even challenged ourselves with an exercise to solidify our understanding. Rust's focus on performance and safety makes it an excellent choice for system-level programming and low-level optimizations. As you continue your journey with Rust, remember that practice is key to mastering any programming language. Embrace the power of Rust's expressive syntax and its robust features to build efficient and secure applications. Happy coding!

Top comments (0)