RUST

Rust Introduction Guide: Ownership System and Memory Safety

Rust is a systems programming language that guarantees memory safety at compile time while maintaining C/C++ performance. Without a garbage collector, this is made possible through its core Ownership system.

Why Rust?

Research from Microsoft and Google shows that over 70% of security vulnerabilities in C/C++ programs stem from memory-related bugs (use-after-free, buffer overflow, null pointer dereference). Rust eliminates these issues at compile time rather than at runtime.

  • C/C++ level performance: Zero-cost abstractions
  • Memory safety: Prevents memory leaks and dangling pointers without a garbage collector
  • Thread safety: Compiler prevents data races proactively
  • Modern ecosystem: Cargo package manager, rich standard library

Core Concept: Ownership

All of Rust's memory safety guarantees stem from three ownership rules.

  • Each value has exactly one owner
  • There can only be one owner at a time
  • When the owner goes out of scope, the value is automatically dropped
fn main() {
    let s1 = String::from("hello"); // s1 is the owner
    let s2 = s1;                    // ownership moves to s2
    // println!("{}", s1);          // compile error! s1 is no longer valid
    println!("{}", s2);             // OK
} // s2 goes out of scope, memory is automatically freed

Borrowing and References

To use a value without transferring ownership, use a reference (&). This is called borrowing.

fn calculate_length(s: &String) -> usize { // s is a reference (borrowed)
    s.len()
} // s goes out of scope but the original is not dropped

fn main() {
    let s = String::from("hello");
    let len = calculate_length(&s); // pass a reference
    println!("The length is {}.", len); // s is still valid
}

Mutable References and the Borrow Checker

Rust's Borrow Checker enforces two rules.

  • Multiple immutable references (&T) are allowed simultaneously
  • Only one mutable reference (&mut T) is allowed at a time (cannot coexist with immutable references)
fn main() {
    let mut s = String::from("hello");
    let r1 = &s;      // immutable reference 1
    let r2 = &s;      // immutable reference 2 - OK
    // let r3 = &mut s; // error! cannot borrow as mutable while immutable refs exist
    println!("{} {}", r1, r2);
    let r3 = &mut s;  // now OK
    r3.push_str(" world");
}

Lifetimes

Lifetimes are syntax for explicitly expressing the scope in which references are valid. The compiler infers most lifetimes, but explicit annotations are needed when multiple references are involved.

// 'a is a lifetime parameter: the return value's lifetime is the shorter of x and y
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

Practical Use: When to Learn Rust

Rust is not optimal for every situation. Consider adoption based on these criteria.

  • Suitable for: Systems programming, embedded systems, CLI tools, WebAssembly, high-performance API servers
  • Be cautious when: Rapid prototyping, small scripts, team lacks Rust experience
F

Fit System

A developer with 10+ years of software engineering experience, specializing in high-performance system design and cloud-native architecture.