Rust é a linguagem de programação de sistemas de crescimento mais rápido em 2026. Usada no kernel Linux, Android, Windows, AWS e Meta, Rust oferece desempenho de nível C com segurança de memória garantida em tempo de compilação. Este guia para iniciantes cobre os principais conceitos do Rust sem sobrecarga de jargões.
📋 Table of Contents
Por que ferrugem em 2026?
- Segurança de memória– sem ponteiros nulos, sem buffer overflows, sem uso após liberação
- Desempenho— corresponde a C/C++ com zero sobrecarga de tempo de execução
- Simultaneidade destemida— corridas de dados capturadas em tempo de compilação
- Ferramentas modernas— Gerenciador de pacotes de carga, rustfmt, clippy, analisador de ferrugem
- WebAssembly— execute Rust no navegador em velocidade quase nativa
- Amei 9 anos consecutivos— linguagem mais adorada na pesquisa Stack Overflow
Instalação
# Install rustup (manages Rust versions)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Verify
rustc --version # rustc 1.79.0
cargo --version # cargo 1.79.0
# Create new project
cargo new hello_rust
cd hello_rust
# Run
cargo run
# Build release (optimized)
cargo build --release
Variáveis, tipos e funções
// Variables are immutable by default
fn main() {
let x = 5; // immutable
let mut y = 10; // mutable
y += 1; // OK
// x += 1; // ERROR: cannot assign to immutable variable
// Type annotation (usually inferred)
let name: String = String::from("Alice");
let age: u32 = 30;
let pi: f64 = 3.14159;
let active: bool = true;
// Constants
const MAX_SIZE: usize = 1024;
// Shadowing — create new variable with same name
let spaces = " ";
let spaces = spaces.len(); // now a number, not a string
println!("Name: {name}, Age: {age}");
}
// Functions
fn add(a: i32, b: i32) -> i32 {
a + b // no semicolon = expression, this is the return value
}
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
// Multiple return values via tuple
fn min_max(numbers: &[i32]) -> (i32, i32) {
let min = *numbers.iter().min().unwrap();
let max = *numbers.iter().max().unwrap();
(min, max)
}
let (lo, hi) = min_max(&[3, 1, 4, 1, 5, 9]);
println!("min={lo}, max={hi}");
Propriedade – Conceito Central de Rust
O sistema de propriedade do Rust é o que torna possível a segurança da memória sem coleta de lixo:
// Rule 1: Each value has exactly one owner
// Rule 2: When owner goes out of scope, value is dropped (freed)
// Rule 3: Ownership can be transferred (moved)
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 is MOVED to s2
// println!("{s1}"); // ERROR: s1 is no longer valid
// Clone to make a copy
let s3 = String::from("hello");
let s4 = s3.clone(); // deep copy, both valid
println!("{s3} {s4}");
// Stack types (Copy trait): no move needed
let n1 = 5;
let n2 = n1; // copied, n1 still valid
println!("{n1} {n2}");
}
// Passing to functions transfers ownership
fn takes_ownership(s: String) {
println!("{s}");
} // s is dropped here
fn gives_ownership() -> String {
String::from("new string") // moved to caller
}
fn main() {
let s = String::from("hello");
takes_ownership(s);
// s no longer valid here!
let s2 = gives_ownership(); // s2 owns the new string
}
Referências e empréstimos
// Borrow without taking ownership using &
fn calculate_length(s: &String) -> usize {
s.len()
} // s goes out of scope, but doesn't drop the String (it's borrowed)
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1); // pass reference
println!("{s1} has {len} characters"); // s1 still valid!
// Mutable references
let mut s = String::from("hello");
change(&mut s); // pass mutable reference
println!("{s}"); // "hello, world"
}
fn change(s: &mut String) {
s.push_str(", world");
}
// Rules:
// 1. Any number of immutable references
// 2. OR exactly one mutable reference
// 3. Never both at the same time
// This prevents data races at compile time!
Estruturas e Métodos
#[derive(Debug, Clone)] // auto-implement Debug and Clone
struct Rectangle {
width: f64,
height: f64,
}
impl Rectangle {
// Associated function (like static method)
fn new(width: f64, height: f64) -> Self {
Rectangle { width, height }
}
fn square(size: f64) -> Self {
Rectangle { width: size, height: size }
}
// Method — takes &self (immutable borrow)
fn area(&self) -> f64 {
self.width * self.height
}
fn perimeter(&self) -> f64 {
2.0 * (self.width + self.height)
}
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
// Mutable method
fn scale(&mut self, factor: f64) {
self.width *= factor;
self.height *= factor;
}
}
fn main() {
let mut rect = Rectangle::new(30.0, 50.0);
println!("{rect:?}"); // Debug output: Rectangle { width: 30.0, height: 50.0 }
println!("Area: {}", rect.area());
rect.scale(2.0);
println!("After scaling: {}x{}", rect.width, rect.height);
}
Enums e correspondência de padrões
// Enum with data
#[derive(Debug)]
enum Shape {
Circle(f64), // radius
Rectangle(f64, f64), // width, height
Triangle { base: f64, height: f64 }, // named fields
}
impl Shape {
fn area(&self) -> f64 {
match self {
Shape::Circle(r) => std::f64::consts::PI * r * r,
Shape::Rectangle(w, h) => w * h,
Shape::Triangle { base, height } => 0.5 * base * height,
}
}
}
// Option<T> — replace null
fn find_user(id: u32) -> Option<String> {
if id == 1 { Some(String::from("Alice")) } else { None }
}
fn main() {
match find_user(1) {
Some(name) => println!("Found: {name}"),
None => println!("Not found"),
}
// if let — match one arm
if let Some(name) = find_user(1) {
println!("User: {name}");
}
// unwrap_or, map, and_then
let name = find_user(2).unwrap_or(String::from("Guest"));
let length = find_user(1).map(|n| n.len()).unwrap_or(0);
}
// Result<T, E> — error handling
fn parse_number(s: &str) -> Result<i32, std::num::ParseIntError> {
s.trim().parse()
}
fn main() {
match parse_number("42") {
Ok(n) => println!("Parsed: {n}"),
Err(e) => println!("Error: {e}"),
}
// ? operator — propagate errors
fn add_strings(a: &str, b: &str) -> Result<i32, std::num::ParseIntError> {
let x: i32 = a.trim().parse()?; // return Err if fails
let y: i32 = b.trim().parse()?;
Ok(x + y)
}
}
Coleções
use std::collections::HashMap;
fn main() {
// Vec — dynamic array
let mut v: Vec<i32> = Vec::new();
v.push(1);
v.push(2);
v.push(3);
// Iterate
for n in &v { print!("{n} "); }
// Useful methods
v.retain(|x| *x > 1); // remove elements
let sum: i32 = v.iter().sum();
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
// HashMap
let mut scores: HashMap<String, u32> = HashMap::new();
scores.insert(String::from("Alice"), 95);
scores.insert(String::from("Bob"), 87);
// Only insert if not present
scores.entry(String::from("Alice")).or_insert(100);
// Lookup
if let Some(score) = scores.get("Alice") {
println!("Alice: {score}");
}
// Iterate
for (name, score) in &scores {
println!("{name}: {score}");
}
}
Carga: Gerenciador de Pacotes
# Cargo.toml
[package]
name = "my_app"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
anyhow = "1.0"
clap = { version = "4.0", features = ["derive"] }
cargo add serde --features derive # add dependency
cargo update # update dependencies
cargo test # run tests
cargo bench # run benchmarks
cargo doc --open # generate and open docs
cargo clippy # linting
cargo fmt # auto-format
Roteiro de primeiros passos
- Leia os primeiros 8 capítulos deO livro da ferrugem(gratuito em doc.rust-lang.org)
- CompletoFarfalhar— exercícios interativos
- Crie uma ferramenta CLI combater palmas
- Escreva uma API REST comaxum
- Contribua para um projeto Rust de código aberto
A curva de aprendizado de Rust é real, mas a recompensa é permanente. Depois de internalizar a propriedade e os empréstimos, você escreverá um código mais seguro e rápido em todas as linguagens. O ecossistema Rust em 2026 está maduro o suficiente para servidores web, CLIs, incorporados e WebAssembly.
🔗 Share this article
✍️ Leave a Comment