🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Guia de programação Rust para iniciantes 2026: propriedade, estruturas e carga

⏱️6 min read  ·  1,250 words

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.

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

  1. Leia os primeiros 8 capítulos deO livro da ferrugem(gratuito em doc.rust-lang.org)
  2. CompletoFarfalhar— exercícios interativos
  3. Crie uma ferramenta CLI combater palmas
  4. Escreva uma API REST comaxum
  5. 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.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা