Rust Programming Basics

Learn Rust fundamentals for Solana development

Rust is the primary programming language for Solana development. Before diving into Solana programs, it's essential to understand Rust fundamentals. This guide covers the core concepts you need to know.

Why Rust?

  • Memory safety without garbage collection
  • Zero-cost abstractions
  • Fearless concurrency
  • Performance comparable to C/C++

Getting Started with Rust

Install Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
rustc --version

Core Concepts

1. Variables and Mutability

Variables in Rust are immutable by default. Use mut for mutable variables.

// Immutable variable
let x = 5;

// Mutable variable
let mut y = 10;
y = 15; // This is allowed

// Constants
const MAX_POINTS: u32 = 100_000;

2. Data Types

Scalar Types:

// Integers: i8, i16, i32, i64, i128, isize
let age: i32 = 30;

// Unsigned integers: u8, u16, u32, u64, u128, usize
let count: u64 = 1000;

// Floating point: f32, f64
let price: f64 = 19.99;

// Boolean
let is_active: bool = true;

// Character
let letter: char = 'A';

Compound Types:

// Tuples
let tup: (i32, f64, bool) = (500, 6.4, true);
let (x, y, z) = tup; // Destructuring

// Arrays
let numbers: [i32; 5] = [1, 2, 3, 4, 5];
let first = numbers[0];

3. Functions

fn main() {
    let result = add(5, 10);
    println!("Result: {}", result);
}

fn add(x: i32, y: i32) -> i32 {
    x + y // No semicolon = return value
}

// Function with multiple returns
fn calculate(x: i32) -> (i32, i32) {
    (x * 2, x * 3)
}

4. Control Flow

If/Else:

let number = 7;

if number < 5 {
    println!("Less than 5");
} else if number > 5 {
    println!("Greater than 5");
} else {
    println!("Equal to 5");
}

// If in a let statement
let result = if number > 5 { "big" } else { "small" };

Loops:

// Loop
let mut counter = 0;
loop {
    counter += 1;
    if counter == 10 {
        break;
    }
}

// While
let mut number = 3;
while number != 0 {
    println!("{number}");
    number -= 1;
}

// For
let arr = [10, 20, 30, 40, 50];
for element in arr {
    println!("{element}");
}

// Range
for number in 1..4 {
    println!("{number}");
}

5. Match Statement

Match is like switch but more powerful:

let number = 7;

match number {
    1 => println!("One"),
    2 | 3 => println!("Two or Three"),
    4..=6 => println!("Four through Six"),
    _ => println!("Something else"),
}

// Match with expressions
let result = match number {
    1..=5 => "small",
    6..=10 => "medium",
    _ => "large",
};

Ownership & Borrowing

Ownership Rules

  1. Each value in Rust has an owner
  2. There can only be one owner at a time
  3. When the owner goes out of scope, the value is dropped
let s1 = String::from("hello");
let s2 = s1; // s1 is moved to s2

// println!("{}", s1); // Error! s1 no longer valid

// Use clone to copy
let s3 = String::from("hello");
let s4 = s3.clone();
println!("{} {}", s3, s4); // Works!

References & Borrowing

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1); // Borrow
    println!("Length of '{}' is {}", s1, len); // s1 still valid
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

// Mutable references
fn main() {
    let mut s = String::from("hello");
    change(&mut s);
}

fn change(s: &mut String) {
    s.push_str(", world");
}

Structs & Enums

Structures

struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

impl User {
    fn new(username: String, email: String) -> User {
        User {
            username,
            email,
            sign_in_count: 0,
            active: true,
        }
    }
    
    fn deactivate(&mut self) {
        self.active = false;
    }
}

fn main() {
    let mut user1 = User::new(
        String::from("user123"),
        String::from("user@example.com")
    );
    user1.deactivate();
}

Enumerations

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

impl Message {
    fn call(&self) {
        match self {
            Message::Quit => println!("Quit"),
            Message::Move { x, y } => println!("Move to {}, {}", x, y),
            Message::Write(text) => println!("Write: {}", text),
            Message::ChangeColor(r, g, b) => println!("Color: {}, {}, {}", r, g, b),
        }
    }
}

// Option and Result are built-in enums
let some_number: Option = Some(5);
let absent_number: Option = None;

Error Handling

use std::fs::File;
use std::io::Read;

// Using Result
fn read_file(filename: &str) -> Result {
    let mut file = File::open(filename)?; // ? operator
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

fn main() {
    match read_file("hello.txt") {
        Ok(contents) => println!("{}", contents),
        Err(error) => println!("Error: {}", error),
    }
}

Modules & Testing

Modules:

mod math {
    pub fn add(a: i32, b: i32) -> i32 {
        a + b
    }
    
    pub fn multiply(a: i32, b: i32) -> i32 {
        a * b
    }
}

fn main() {
    let result = math::add(5, 10);
    println!("Result: {}", result);
}

Testing:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(math::add(2, 3), 5);
    }

    #[test]
    fn test_multiply() {
        assert_eq!(math::multiply(2, 3), 6);
    }
}

Learning Resources

📖

The Rust Book

Official comprehensive guide to learning Rust.

Read Book →
🎯

Rust by Example

Learn Rust through annotated example programs.

View Examples →
🧩

Rustlings

Small exercises to get you used to reading and writing Rust code.

Start Exercises →
🎓

Exercism Rust Track

Practice Rust with mentored code reviews.

Join Track →

Next Steps

Now that you understand Rust basics, you're ready to learn Solana-specific concepts! Continue to Solana Basics to start building blockchain programs.

⛓️

Solana Basics

Learn Solana fundamentals and blockchain concepts.

Start Learning →

Anchor Framework

Master the most popular Solana development framework.

Learn Anchor →