😎Common Programming Concepts

Common programming concepts in Rust

Variable

Declare a variable

fn main() {
    // Create a variable
    let a = 5;
    println!("a: {}", a);
}

Immutability

fn main() {
    // Mutability
    // let b = 10; => error
    let mut b = 10;
    b = 20;

    println!("b: {}", b);
}

Shadowing

The different between mutability and shadowing is that with mutability, you’re modifying a single variable, while with shadowing, you’re create two separate variables, and one of them is shadowing the other.

Scopes

Because the outer scope can’t access the variable in the inner scope, therefore, we’ll get an error when we’re trying to access the variable in the inner scope from the outer scope.

Data Types

Category
Data Type
Description
Size (on 64-bit systems)

Scalar Types

i8, i16, i32, i64, i128

Signed integers

1, 2, 4, 8, 16 bytes

u8, u16, u32, u64, u128

Unsigned integers

1, 2, 4, 8, 16 bytes

f32, f64

Floating-point numbers

4, 8 bytes

char

Character (Unicode scalar value)

4 bytes

bool

Boolean value (true or false)

1 byte

Compound Types

Array

Fixed-size collection of elements of the same type

Varies depending on element type and size

Slice

Dynamically sized view into an underlying array

Same as underlying array

Tuple

Fixed-size collection of elements of potentially different types

Varies depending on element types

Struct

User-defined composite data type with named fields

Varies depending on field types

Enum

User-defined type representing a set of variants

Varies depending on variant types

Reference Types

&T

Reference to a value of type T

8 bytes

&mut T

Mutable reference to a value of type T

8 bytes

Other Types

Option<T>

Represents an optional value of type T, can be Some(value) or None

8 bytes (includes 1 byte for discriminant)

Result<T, E>

Represents the outcome of an operation, either Ok(value) or Err(error)

16 bytes (includes 1 byte for discriminant)

Notes:

  • The size of some data types may vary depending on the target architecture (32-bit vs. 64-bit).

  • Rust has additional data types like raw pointers, functions, and closures, which are more advanced and not covered in this basic table.

Scalar Types

Compound Types

Constants

Key Characteristics of Constants:

  • Immutability: The defining characteristic of constants is their unchangeable nature. Once assigned a value, a constant cannot be modified throughout the program's execution.

  • Explicit Type Annotation: Unlike variables where the compiler can infer the type based on the assigned value, constants require explicit type declaration. This improves code clarity and avoids potential type mismatches.

  • Scope: Constants can be declared within various scopes, including the global scope, allowing for program-wide access if necessary. However, it's generally recommended to keep constants within the appropriate scope for better organization and encapsulation.

  • Constant Expressions: The value assigned to a constant must be a constant expression. This means the expression can be evaluated entirely at compile time, ensuring the value is known before the program runs.

  • Naming Convention: Rust adheres to the screaming snake case convention for constants. This means all letters are uppercase, and underscores separate words (e.g., MAX_VALUE).

Static Variables

Key Characteristics of Constants:

  • Immutability: Unlike the constants, static variables can be marked as mutable using mut keyword. However, accessing or modifying a mutable static variable is unsafe, therefore, those operations must be done within an unsafe block.

  • Memory management: When using constant variables, the value of the constant will be inline. The constants do not occupy a specific location in memory. Constants are allowed to duplicate their data whenever they’re used.

  • On the other hand, static variables do occupy a specific location in memory, which means there’s only one instance of the value. It means, a static variable has a fixed address in memory, therefore, using that value will always access the same data.

In general, it's best practice to use constants whenever possible. Static variables should be reserved for specific scenarios. These scenarios include:

  • Storing large amounts of data: Constants are limited in size by the type they represent. If you need to store a significant amount of data that cannot be easily divided into smaller pieces, a static variable might be necessary.

  • Needing a single, fixed memory location: Static variables have a unique memory address throughout the program's execution. This property can be useful in limited situations.

  • Using interior mutability: In rare cases, you might need a data structure that allows modification of specific parts while maintaining immutability for the overall structure. This advanced technique, known as interior mutability, often relies on static variables.

Functions

Rust code uses snake case as the conventional style for function and variable names, in which all letters are lowercase and underscores separate words.

Rust functions use an arrow (>) followed by the type of value the function will return (e.g., > u32) to represent the return type of the function. If no return type is specified, the function returns the unit type (()), which essentially means it doesn't return a value.

Control Flows in Rust

if Expressions

  • Used for simple conditional execution.

  • Checks a boolean expression.

  • If the expression is true, the code block following the if keyword is executed.

if-else Statements

else if

if let

Structure:

  • <pattern>: This defines the pattern you want to match against the value from the <expression>. It can be a variable name, a literal value, or a more complex structure like a tuple or struct.

  • <expression>: This is the value you want to check against the pattern.

Functionality:

  • If the pattern in <pattern> matches the value from <expression>, the code block within the curly braces is executed.

  • Any variables defined within the pattern are bound to the corresponding values from the expression, making them accessible within the code block.

  • If the pattern doesn't match, the if let block is skipped, and execution continues after it.

Loops

  • break and continue:

    • break: Exits a loop prematurely.

    • continue: Skips the current iteration of a loop and moves to the next.

Match Expressions

Last updated