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;
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.
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;
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;
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;
By default, variables declared as bool are automatically set to false.
let is_updated: bool; // will be false
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
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
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;
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;
Character
This type is similar to character in other programming languages and is represented with the char keyword.
Example:
let alphabet: char = 'a';
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];
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:
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
}
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];
}
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];
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); // []
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]
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]
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
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");
}
}
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");
}
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}");
}
}
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}");
}
}
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;
}
}
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}");
}
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
}
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)