Skip to content

Latest commit

 

History

History
566 lines (363 loc) · 9.67 KB

27-Tutorial.md

File metadata and controls

566 lines (363 loc) · 9.67 KB

Learn Rust

We use the println! macro

use print! macro

{} is a placeholder which is replaced by the value of the variable after the comma

add text with the placeholder to format our output

Note: As per Rust's naming convention, we use uppercase for the name of constants.

Rust Data Types

i32 signed intgeger

u32 unsigned integer


Categories of Integer Data Types in Rust

Depending on the size of data, we can further classify the signed and unsigned integer type into various categories:

Size Signed Unsigned
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128

Search: table in markdown

Result: Extended Syntax | Markdown Guide



Type Inference

fn main() {
    let x = 51;

    println!("x = {}", x);
}

Output:

x = 51

Here, you can see that we haven't mentioned the data type of x variable.

It is because Rust will automatically set i32 as the type (default type for integer variable) by looking at the value 51.

Rust Data Types


Matching a Variable in Rust

fn main() {
    let x = 2;

    // use of match expression to pattern match against variable x
    match x {
        1 => println!("x is 1"),
        2 => println!("x is 2"),
        _ => println!("x is something else"),
    }
}

Ouput

x is 2

Matching an Enum In Rust

fn main() {
    enum Color {
        Red,
        Green,
        Blue,
    }

    let my_color = Color::Green;

    // use of match expression to match against an enum variant
    match my_color {
        Color::Red => println!("The color is red"),
        Color::Green => println!("The color is green"),
        Color::Blue => println!("The color is blue"),
    }
}

Output

The color is green

Matching Option and Result Type in Rust

The most common case for

pattern matching

is with

Option and Result enum types.

Both the Option and Result type have two variants.

Option type has:

  • None → to indicate failure with no value

  • Some(T) → a value with type T

Result type has:

  • Ok(T) → operation succeeded with value T

  • Err(E) → operation failed with an error E

Let's look at examples of how we can use pattern

matching on these types.


Example: Matching Option Type in Rust

fn main() {
    let my_option: Option<i32> = Some(222);
    
    // use of match expression to match Option type
    match my_option {
        Some(value) => println!("The option has a value of {}", value),
        None => println!("The option has no value"),
    }
}
The option has a value of 222

In this example, my_option is an Option type that contains either a Some variant with an i32 value or a None variant.

The match expression compares the value of my_option to the Some and None variants, and binds the value of Some variant to the value variable.

When a match is found, the corresponding code block is executed.

match.jpg

End of Option Type Pattern matching.

Example: Matching Result Type in Rust

ResultType.jpg

ResultTypeContinued.jpg

IfLetShorthandMatch.png


fn main() {
    // initialization of array with data type
    let numbers: [i32; 5] = [1, 2, 3, 4, 5];
    
    println!("Array of numbers = {:?}", numbers);
}
Array of numbers = [1, 2, 3, 4, 5]

Revision: Different Ways to Create Array in Rust

fn main() {
    // an array without data type
    let a = [5, 4, 3, 2, 1];
    
    // an array with data type and size
    let b: [i32; 5] = [1, 2, 3, 4, 5];
    
    // an array with default values
    let c = [3; 5];
    
    println!("a = {:?}", a);
    println!("b = {:?}", b);
    println!("c = {:?}", c);
}

Output

a = [5, 4, 3, 2, 1]
b = [1, 2, 3, 4, 5]
c = [3, 3, 3, 3, 3]

Note:

We use :? in the println! function to print an entire array.


RustArray.png


Array without Data Type in Rust:

fn main() {
    // initialization of array without data type

    let numbers = [1, 2, 3, 4, 5];
    println!("array of numbers = {:?}, numbers;
}

RustArrayNotes.jpg


Example: Access Array Elements

fn main() {
    let colors = ["red", "green", "blue"];
    
    // accessing element at index 0
    println!("1st Color: {}", colors[0]);

    // accessing element at index 1
    println!("2nd Color: {}", colors[1]);

    // accessing element at index 2
    println!("3rd Color: {}", colors[2]);
}

Output

1st Color: red
2nd Color: green
3rd Color: blue

Mutable array in Rust

fn main() {
    let mut numbers: [i32; 5] = [1, 2, 3, 4, 5];
    
    println!("original array = {:?}", numbers);
    
    // change the value of the 3rd element in the array
    numbers[2] = 0;
    
    println!("changed array = {:?}", numbers);
}

Output

original array = [1, 2, 3, 4, 5]
changed array = [1, 2, 0, 4, 5]

Reassignment using:

    numbers[2] = 0;

RustArrayMutReassign.png


Looping Through an Array in Rust

fn main() {
    let colors = ["red", "green", "blue"];
    
    // loop through an array to print its index and value
    for index in 0..3 {
        println!("Index: {} -- Value: {}", index, colors[index]);
    }
}

Output

Index: 0 -- Value: red
Index: 1 -- Value: green
Index: 2 -- Value: blue


Rust Slice

fn main() {
    // an array of numbers
    let numbers = [1, 2, 3, 4, 5];
    
    // create a slice of 2nd and 3rd element
    let slice = &numbers[1..3];
    
    println!("array = {:?}", numbers);
    println!("slice = {:?}", slice);
}
array = [1, 2, 3, 4, 5]
slice = [2, 3]

Note

A slice is not the actual data like integers or floats but a reference/pointer to the data block. That's why we have used the & symbol before the variable name.


Omit Indexes of a Rust Slice

fn main() {
    let numbers = [1, 2, 3, 4, 5];

    // omit the start index
    let slice = &numbers[..3];

    println!("array = {:?}", numbers);
    println!("slice = {:?}", slice);
}
array = [1, 2, 3, 4, 5]
slice = [1, 2, 3]

RustSliceOmitStart.png


2. Omitting the End Index of a Slice

fn main() {
    let numbers = [1, 2, 3, 4, 5];

    // omit the end index
    let slice = &numbers[2..];

    println!("array = {:?}", numbers);
    println!("slice = {:?}", slice);
}

Output

array = [1, 2, 3, 4, 5]
slice = [3, 4, 5]

Note

Here,

&numbers[2..]

includes 2.. without the end index.

This means

the slice starts from index 2

and

goes up to index 5 (exclusive).

It is equivalent to

&numbers[2..5]

3. Omitting both Start and End Index of a Slice

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    
    // omit the start index and the end index
    // reference the whole array
    let slice = &numbers[..];

    println!("array = {:?}", numbers);
    println!("slice = {:?}", slice);
}

Output

array = [1, 2, 3, 4, 5]
slice = [1, 2, 3, 4, 5]

Note

Here,

&numbers[..]

includes ..

without

the start and end index.

This means the slice starts from

index 0 and goes up to

index 5 (exclusive).

It is equivalent to

&numbers[0..5]

which will produce

the same slice and

will reference the whole array.


Mutable Slice in Rust

fn main() {
    // mutable array
    let mut colors = ["red", "green", "yellow", "white"];
    
    println!("array = {:?}", colors);

    // mutable slice
    let sliced_colors = &mut colors[1..3]; // Note 1
    
    println!("original slice = {:?}", sliced_colors);

    // change the value of the original slice at the first index
    sliced_colors[1] = "purple"; // Note 2

    println!("changed slice = {:?}", sliced_colors);
}

Output

array = ["red", "green", "yellow", "white"]
original slice = ["green", "yellow"]
changed slice = ["green", "purple"]

Note 1

Here, we have created a

mutable array

colors.

Then, we have created a

mutable slice

sliced_colors

with

&mut array[1..3]

Note 2

Now, we can change the content of the mutable slice,

sliced_colors[1] = "purple"

We change the value of original slice

sliced_colors at the

1st index from

"yellow" to "purple".


28-Tutorial-Tuple-onwards.md