Rust
Systems language with memory safety guarantees enforced at compile time via the borrow checker.
Systems language with memory safety guarantees enforced at compile time via the borrow checker.
Rust enforces memory safety at compile time through its ownership and borrow-checker system — no garbage collector, no null pointer exceptions, no data races by default.
Every value in Rust has exactly one owner. When the owner goes out of scope, the value is dropped (memory freed).
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 is MOVED into s2; s1 is now invalid
// println!("{}", s1); // compile error: use of moved value
println!("{}", s2); // fine
}
This makes use-after-free impossible by construction.
You can borrow a value without taking ownership — either immutably (many borrows ok) or mutably (one at a time, exclusive):
fn length(s: &String) -> usize {
s.len() // borrows s, does not own it
}
fn append(s: &mut String) {
s.push_str(", world"); // mutable borrow, exclusive
}
The borrow checker ensures: no mutable reference can coexist with any other reference to the same data. This eliminates data races at the type-system level.
Rust has no exceptions. Errors are values:
use std::fs;
use std::io;
fn read_config(path: &str) -> Result<String, io::Error> {
fs::read_to_string(path)
}
fn main() {
match read_config("config.toml") {
Ok(contents) => println!("{}", contents),
Err(e) => eprintln!("error: {}", e),
}
}
The ? operator propagates errors up the call stack without boilerplate:
fn process() -> Result<(), io::Error> {
let contents = fs::read_to_string("config.toml")?;
// if the above errors, ? returns early with that error
println!("{}", contents);
Ok(())
}
Traits are Rust’s interfaces — they define shared behavior:
trait Summary {
fn summarize(&self) -> String;
fn author(&self) -> String { String::from("(unknown)") } // default impl
}
struct Article { title: String, body: String }
impl Summary for Article {
fn summarize(&self) -> String {
format!("{}: {}...", self.title, &self.body[..100])
}
}