Skip to content

yoursanonymous/Rust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rust Language: High-Level Notes for Solana & Modern Development

Table of Contents

  1. Introduction to Rust
  2. Getting Started
  3. Core Concepts
  4. Ownership, Borrowing, and Lifetimes
  5. Data Types & Structures
  6. Control Flow
  7. Functions, Closures, and Traits
  8. Error Handling
  9. Modules, Crates, and Packages
  10. Concurrency & Asynchronous Programming
  11. Macros & Metaprogramming
  12. Interfacing with C & FFI
  13. Rust for Solana Development
  14. Advanced Topics
  15. Useful Resources

Introduction to Rust

  • Rust is a systems programming language focused on safety, speed, and concurrency.
  • Memory safety without garbage collection.
  • Used in blockchain (e.g., Solana), web servers, embedded, and more.

Getting Started

  • Install via rustup: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  • Project structure: Cargo.toml (manifest), src/main.rs (entry point)
  • Build & run: cargo build, cargo run
  • Hello World Example:
    fn main() {
        println!("Hello, world!");
    }

Core Concepts

  • Variables: Immutable by default, use mut for mutability.
    let x = 5; // immutable
    let mut y = 10; // mutable
    y += 2;
    println!("y: {}", y);
  • Constants: Must have type annotation, set at compile time.
    const PI: f64 = 3.1415;
    println!("PI: {}", PI);
  • Shadowing: Redeclare variable with let.
    let z = 1;
    let z = z + 2; // shadows previous z
    println!("z: {}", z);

Ownership, Borrowing, and Lifetimes

  • Ownership: Each value has a single owner; value dropped when owner goes out of scope.
    let s = String::from("hello");
    let t = s; // s is moved to t, s is no longer valid
    // println!("{}", s); // error!
    println!("{}", t);
  • Borrowing: References (&T for immutable, &mut T for mutable).
    fn print_length(s: &String) {
        println!("Length: {}", s.len());
    }
    let s = String::from("borrowed");
    print_length(&s);
  • Mutable Borrowing:
    fn add_exclamation(s: &mut String) {
        s.push('!');
    }
    let mut s = String::from("hi");
    add_exclamation(&mut s);
    println!("{}", s);
  • Lifetimes: Ensure references are valid.
    fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
        if x.len() > y.len() { x } else { y }
    }
    let a = "abc";
    let b = "longer string";
    println!("{}", longest(a, b));

Data Types & Structures

  • Scalar Types: i32, u32, f64, bool, char
    let a: i32 = -42;
    let b: f64 = 3.14;
    let c: bool = true;
    let d: char = 'R';
  • Compound Types: Tuples (i32, f64), Arrays [i32; 3]
    let tup: (i32, &str) = (10, "tuple");
    let arr: [u8; 3] = [1, 2, 3];
    println!("{} {}", tup.0, tup.1);
    println!("First: {}", arr[0]);
  • Structs: Custom data types.
    struct User {
        name: String,
        age: u8,
    }
    let user = User { name: String::from("Alice"), age: 30 };
    println!("{} is {}", user.name, user.age);
  • Tuple Structs:
    struct Color(u8, u8, u8);
    let black = Color(0, 0, 0);
    println!("Black: {}, {}, {}", black.0, black.1, black.2);
  • Enums: Tagged unions.
    enum Direction { North, East, South, West }
    let dir = Direction::East;
    match dir {
        Direction::North => println!("Up"),
        Direction::East => println!("Right"),
        Direction::South => println!("Down"),
        Direction::West => println!("Left"),
    }
  • Pattern Matching: match, if let
    let some_number = Some(7);
    match some_number {
        Some(n) if n > 5 => println!("Big number: {}", n),
        Some(n) => println!("Small number: {}", n),
        None => println!("No number"),
    }

Control Flow

  • if/else: Standard conditional logic.
    let temp = 30;
    if temp > 25 {
        println!("Hot!");
    } else {
        println!("Cool!");
    }
  • loop, while, for: Iteration constructs.
    let mut count = 0;
    loop {
        if count == 3 { break; }
        println!("loop: {}", count);
        count += 1;
    }
    
    let mut n = 0;
    while n < 3 {
        println!("while: {}", n);
        n += 1;
    }
    
    for i in 0..3 {
        println!("for: {}", i);
    }
  • break, continue, return: Control statements.
    for i in 0..5 {
        if i == 2 { continue; }
        if i == 4 { break; }
        println!("i: {}", i);
    }
    fn early_return(x: i32) -> i32 {
        if x > 0 { return x; }
        0
    }
    println!("{}", early_return(5));

Functions, Closures, and Traits

  • Functions:
    fn square(x: i32) -> i32 {
        x * x
    }
    println!("{}", square(4));
  • Closures: Anonymous functions, can capture environment.
    let numbers = vec![1, 2, 3];
    let doubled: Vec<_> = numbers.iter().map(|x| x * 2).collect();
    println!("{:?}", doubled);
  • Traits: Define shared behavior (interfaces).
    trait Greet {
        fn greet(&self);
    }
    struct Person;
    impl Greet for Person {
        fn greet(&self) {
            println!("Hello!");
        }
    }
    let p = Person;
    p.greet();
  • Impl: Implement methods/traits for types.
    struct Counter { value: i32 }
    impl Counter {
        fn increment(&mut self) { self.value += 1; }
    }
    let mut c = Counter { value: 0 };
    c.increment();
    println!("{}", c.value);

Error Handling

  • Panic: Unrecoverable errors (panic! macro).
    // panic!("Something went wrong!");
  • Result & Option: Recoverable errors and optional values.
    fn safe_divide(x: f64, y: f64) -> Result<f64, String> {
        if y == 0.0 {
            Err(String::from("Cannot divide by zero"))
        } else {
            Ok(x / y)
        }
    }
    match safe_divide(10.0, 2.0) {
        Ok(result) => println!("Result: {}", result),
        Err(e) => println!("Error: {}", e),
    }
  • ? Operator: Propagate errors easily.
    use std::fs::File;
    fn open_file() -> std::io::Result<File> {
        let f = File::open("foo.txt")?;
        Ok(f)
    }

Modules, Crates, and Packages

  • Modules: Organize code with mod, pub mod.
    mod math {
        pub fn add(a: i32, b: i32) -> i32 { a + b }
    }
    println!("{}", math::add(2, 3));
  • Crates: Compilation units (binary or library).
    • Example: rand crate for random numbers.
    use rand::Rng;
    let mut rng = rand::thread_rng();
    let n: u8 = rng.gen_range(0..10);
    println!("Random: {}", n);
  • Packages: One or more crates, managed by Cargo.
    • Example: A package with both a binary and a library crate.
  • Use: Import items with use.
    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert("key", 42);
    println!("{:?}", map);

Concurrency & Asynchronous Programming

  • Threads: std::thread::spawn
    use std::thread;
    let handle = thread::spawn(|| {
        println!("Hello from a thread!");
    });
    handle.join().unwrap();
  • Channels: Message passing (std::sync::mpsc)
    use std::sync::mpsc;
    let (tx, rx) = mpsc::channel();
    std::thread::spawn(move || {
        tx.send(42).unwrap();
    });
    println!("Received: {}", rx.recv().unwrap());
  • Mutex, Arc: Shared state concurrency.
    use std::sync::{Arc, Mutex};
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];
    for _ in 0..5 {
        let counter = Arc::clone(&counter);
        let handle = std::thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }
    for handle in handles { handle.join().unwrap(); }
    println!("Result: {}", *counter.lock().unwrap());
  • Async/Await: Asynchronous programming (async fn, .await)
    async fn say_hello() {
        println!("Hello async!");
    }
    // In main: futures::executor::block_on(say_hello());
  • Tokio, async-std: Popular async runtimes.
    • Example: Tokio timer
    // tokio::time::sleep(std::time::Duration::from_secs(1)).await;

Macros & Metaprogramming

  • Macros: Code generation (macro_rules!, procedural macros)
    macro_rules! repeat {
        ($val:expr, $times:expr) => {
            for _ in 0..$times {
                println!("{}", $val);
            }
        };
    }
    repeat!("Hi", 3);
  • Derive Macros: #[derive(Debug, Clone)]
    #[derive(Debug, Clone)]
    struct Point { x: i32, y: i32 }
    let p = Point { x: 1, y: 2 };
    println!("{:?}", p.clone());

Interfacing with C & FFI

  • FFI: Call C code with extern "C" and unsafe blocks.
    extern "C" {
        fn abs(input: i32) -> i32;
    }
    unsafe {
        println!("Abs: {}", abs(-3));
    }
  • Bindgen: Generate Rust bindings for C libraries.
    • Example: Use bindgen CLI to generate Rust FFI bindings from C headers.

Rust for Solana Development

  • Solana Programs: On-chain programs (smart contracts) written in Rust.
    // Entry point for a Solana program
    use solana_program::{account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, pubkey::Pubkey};
    entrypoint!(process_instruction);
    fn process_instruction(
        _program_id: &Pubkey,
        _accounts: &[AccountInfo],
        _instruction_data: &[u8],
    ) -> ProgramResult {
        Ok(())
    }
  • Borsh/Serde: Serialization frameworks for account data.
    use borsh::{BorshDeserialize, BorshSerialize};
    #[derive(BorshSerialize, BorshDeserialize, Debug)]
    pub struct MyAccount { pub data: u64 }
  • Anchor Framework: Abstraction for Solana programs, uses Rust macros and attributes.
    use anchor_lang::prelude::*;
    #[account]
    pub struct MyData { pub value: u64 }
  • CPI (Cross-Program Invocation): Call other Solana programs from your program.
    // Example: invoke CPI using anchor_lang::solana_program::program::invoke
  • Accounts: Use #[account] to define account structures.
    #[account]
    pub struct UserAccount { pub authority: Pubkey, pub balance: u64 }
  • Security: Emphasize safe deserialization, access control, and rent-exemption.
    • Example: Check signer and rent exemption in instruction handler.
  • Testing: Use solana-program-test, Anchor's test framework.
    // Example: #[tokio::test] async fn test_my_program() { ... }

Advanced Topics

  • Unsafe Rust: Manual memory management, raw pointers.
    let x: i32 = 42;
    let r: *const i32 = &x;
    unsafe {
        println!("Value: {}", *r);
    }
  • Zero-cost Abstractions: Compile-time optimizations.
    • Example: Iterators are optimized away at compile time.
    let v = vec![1, 2, 3];
    let sum: i32 = v.iter().sum();
    println!("Sum: {}", sum);
  • Lifetime Elision: Compiler infers lifetimes in simple cases.
    fn first(s: &str) -> &str { &s[0..1] }
    println!("{}", first("hello"));
  • Smart Pointers: Box, Rc, Arc, RefCell.
    use std::rc::Rc;
    let a = Rc::new(5);
    let b = Rc::clone(&a);
    println!("{} {}", a, b);
  • Trait Objects: Dynamic dispatch with dyn Trait.
    trait Animal { fn speak(&self); }
    struct Dog;
    impl Animal for Dog { fn speak(&self) { println!("Woof!"); } }
    let animal: Box<dyn Animal> = Box::new(Dog);
    animal.speak();
  • Generics & Associated Types: Powerful type abstractions.
    fn largest<T: PartialOrd>(list: &[T]) -> &T {
        let mut largest = &list[0];
        for item in list {
            if item > largest { largest = item; }
        }
        largest
    }
    println!("{}", largest(&[1, 2, 3]));
  • Custom Derive & Procedural Macros: Metaprogramming for frameworks like Anchor.
    • Example: #[derive(Accounts)] in Anchor.

Useful Resources


This guide is a high-level overview. For in-depth learning, refer to the official documentation and community resources.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages