O Prelude do Rust: O Que e Importado Automaticamente

Guia completo do prelude do Rust: std::prelude::v1, quais traits e tipos sao importados automaticamente, por que funciona e diferencas entre edicoes.

Visao Geral do Prelude

Quando voce escreve um programa Rust, existem dezenas de tipos e traits que estao sempre disponiveis sem nenhum use explicito. Isso acontece gracas ao prelude — um conjunto de importacoes que o compilador injeta automaticamente em cada arquivo.

E por isso que voce pode usar Vec, String, Option, Result, println!, Some, None, Ok, Err, Box, Clone, Copy, Drop, Iterator e muitos outros sem nenhuma linha de importacao.

O prelude existe em std::prelude::v1 (para a edicao 2015/2018) e std::prelude::rust_2021 (para a edicao 2021), alem de std::prelude::rust_2024 para a edicao 2024. A cada edicao, novos itens podem ser adicionados ao prelude.


O Que Esta no Prelude

Traits Importadas Automaticamente

Estas traits estao disponiveis em todos os escopos sem use:

TraitModuloO Que Faz
Copystd::markerMarca tipos copiaveis bit-a-bit
Sendstd::markerMarca tipos transferiveis entre threads
Syncstd::markerMarca tipos compartilhaveis entre threads
Sizedstd::markerMarca tipos com tamanho conhecido
Unpinstd::markerMarca tipos moviveis dentro de Pin
Dropstd::opsDestrutor customizado
Fnstd::opsClosure chamavel por referencia
FnMutstd::opsClosure chamavel por referencia mutavel
FnOncestd::opsClosure chamavel uma vez (consome)
Clonestd::cloneDuplicacao explicita
PartialEqstd::cmpComparacao de igualdade parcial
Eqstd::cmpComparacao de igualdade total
PartialOrdstd::cmpOrdenacao parcial
Ordstd::cmpOrdenacao total
AsRefstd::convertConversao barata por referencia
AsMutstd::convertConversao barata por referencia mutavel
Intostd::convertConversao infalivel (consumindo)
Fromstd::convertConversao infalivel (construindo)
Defaultstd::defaultValor padrao
Iteratorstd::iterIteracao
Extendstd::iterEstender colecao a partir de iterador
IntoIteratorstd::iterConversao para iterador
DoubleEndedIteratorstd::iterIteracao bidirecional
ExactSizeIteratorstd::iterIterador com tamanho exato
Option (e Some/None)std::optionValor opcional
Result (e Ok/Err)std::resultResultado falivel

Tipos e Funcoes Importados

ItemModuloO Que E
Box<T>std::boxedAlocacao no heap
Stringstd::stringTexto UTF-8 no heap
ToString (trait)std::stringConversao para String
Vec<T>std::vecVetor dinamico
Option<T>std::optionValor opcional
Result<T, E>std::resultResultado falivel
Some, Nonestd::optionVariantes de Option
Ok, Errstd::resultVariantes de Result
drop()std::memFuncao para descartar um valor

Adicionados na Edicao 2021

A edicao 2021 adicionou ao prelude:

ItemModuloO Que Faz
TryFromstd::convertConversao falivel
TryIntostd::convertConversao falivel
FromIteratorstd::iterConstruir colecao a partir de iterador

Adicionados na Edicao 2024

A edicao 2024 adicionou:

ItemModuloO Que Faz
Futurestd::futureTrait base para async
IntoFuturestd::futureConversao para Future

Exemplos Praticos

1. Tudo Que Funciona Sem use

// Nenhum 'use' necessario — tudo vem do prelude!
fn main() {
    // Vec (tipo do prelude)
    let mut numeros: Vec<i32> = Vec::new();
    numeros.push(1);
    numeros.push(2);
    numeros.push(3);

    // Iterator, IntoIterator (traits do prelude)
    let soma: i32 = numeros.iter().sum();
    for n in &numeros {
        print!("{n} ");
    }
    println!("= {soma}");

    // Option, Some, None
    let encontrado: Option<&i32> = numeros.iter().find(|&&x| x > 1);
    match encontrado {
        Some(n) => println!("Encontrado: {n}"),
        None => println!("Nao encontrado"),
    }

    // Result, Ok, Err
    let resultado: Result<i32, String> = Ok(42);
    match resultado {
        Ok(v) => println!("Sucesso: {v}"),
        Err(e) => println!("Erro: {e}"),
    }

    // String e ToString
    let texto = String::from("Rust");
    let numero_str = 42.to_string();
    println!("{texto} {numero_str}");

    // Box
    let boxed = Box::new(vec![1, 2, 3]);
    println!("Box: {boxed:?}");

    // Clone, PartialEq, Default
    let clone = numeros.clone();
    assert_eq!(numeros, clone);
    let vazio: Vec<i32> = Default::default();
    println!("Vazio: {vazio:?}");

    // From, Into
    let s: String = String::from("convertido");
    let s2: String = "tambem convertido".into();
    println!("{s}, {s2}");

    // drop
    let recurso = String::from("descartavel");
    drop(recurso);
    // recurso nao pode mais ser usado

    // AsRef
    fn tamanho(s: impl AsRef<str>) -> usize {
        s.as_ref().len()
    }
    println!("Tamanho: {}", tamanho("teste"));
}

2. O Que NAO Esta no Prelude

// Estes tipos PRECISAM de 'use' explicito:

use std::collections::HashMap;        // Colecoes (exceto Vec)
use std::collections::HashSet;
use std::collections::BTreeMap;
use std::collections::VecDeque;

use std::io::{self, Read, Write};      // I/O
use std::fs::File;                     // Arquivo
use std::path::{Path, PathBuf};        // Caminhos

use std::sync::{Arc, Mutex, RwLock};   // Sincronizacao
use std::sync::mpsc;                   // Canais
use std::thread;                       // Threads

use std::time::{Duration, Instant};    // Tempo
use std::fmt;                          // Formatacao avancada
use std::mem;                          // Manipulacao de memoria
use std::any::Any;                     // Verificacao de tipos runtime

use std::rc::Rc;                       // Reference counting (single-thread)
use std::cell::{Cell, RefCell};        // Interior mutability

fn main() {
    let mut mapa = HashMap::new();
    mapa.insert("chave", 42);

    let arco = Arc::new(Mutex::new(vec![1, 2, 3]));
    let rc = Rc::new("compartilhado");

    let agora = Instant::now();
    let dur = Duration::from_secs(1);

    println!("Mapa: {mapa:?}");
    println!("Arc: {arco:?}");
    println!("Rc: {rc:?}");
    println!("Tempo: {dur:?}, decorrido: {:?}", agora.elapsed());
}

3. Como o Prelude Funciona Internamente

// O compilador injeta isso no inicio de cada arquivo:
// use std::prelude::v1::*; // edicao 2015/2018
// use std::prelude::rust_2021::*; // edicao 2021
// use std::prelude::rust_2024::*; // edicao 2024

// Voce pode verificar o conteudo do prelude:
// https://doc.rust-lang.org/std/prelude/index.html

// Em projetos #![no_std], o prelude vem de core:
// use core::prelude::v1::*;
// Ele contem as mesmas traits, mas sem String, Vec, Box
// (que precisam de alocacao heap)

fn main() {
    // Voce pode importar o prelude explicitamente (desnecessario)
    #[allow(unused_imports)]
    use std::prelude::rust_2021::*;

    // Isso e identico a nao ter nenhum use — o compilador
    // ja importa o prelude automaticamente
    let v = vec![1, 2, 3]; // vec! tambem funciona sem use
    println!("{v:?}");
}

4. Diferencas Entre Edicoes

// Edicao 2015/2018: TryFrom/TryInto NAO estao no prelude
// Voce precisa importar explicitamente:
// use std::convert::{TryFrom, TryInto};

// Edicao 2021+: TryFrom/TryInto estao no prelude
fn demonstrar_edicao_2021() {
    // Sem 'use' necessario na edicao 2021+
    let n: u8 = 42i32.try_into().unwrap();
    let m = u16::try_from(300u32).unwrap();
    println!("{n}, {m}");
}

// Edicao 2024+: Future e IntoFuture estao no prelude
// use std::future::Future; // nao precisa mais na edicao 2024

fn main() {
    demonstrar_edicao_2021();

    // Verificar sua edicao: olhe Cargo.toml
    // [package]
    // edition = "2021"

    println!("Cada edicao pode adicionar itens ao prelude");
    println!("Mas nunca remove itens existentes");
}

5. Prelude Customizado em Crates

// Muitas crates populares definem seu proprio prelude:
// use tokio::prelude::*;
// use serde::prelude::*;
// use diesel::prelude::*;

// Voce pode criar um prelude para seu projeto:
mod meu_prelude {
    // Re-exporta itens frequentemente usados
    pub use std::collections::HashMap;
    pub use std::sync::Arc;
    pub use std::io::Result as IoResult;
}

// Em outros modulos:
// use crate::meu_prelude::*;

fn main() {
    use crate::meu_prelude::*;

    let mut mapa = HashMap::new();
    mapa.insert("funciona", true);

    let arco = Arc::new(42);
    println!("Mapa: {mapa:?}, Arc: {arco}");
    println!("Preludes customizados simplificam imports repetitivos");
}

Padroes Comuns

Por Que HashMap Nao Esta no Prelude?

O prelude inclui apenas os itens mais fundamentais. HashMap e extremamente comum, mas nao e universal — nem todo programa precisa de mapas. A filosofia e manter o prelude minimo para evitar conflitos de nomes e manter o codigo explicito.

Macros no Prelude

As macros vec!, println!, format!, panic!, assert!, assert_eq!, todo!, unimplemented!, unreachable!, dbg! e cfg! sao acessiveis globalmente. Elas nao fazem parte do prelude tecnicamente — sao macros do compilador ou de std exportadas globalmente.

#[no_std] e o Core Prelude

Em projetos #![no_std] (embarcados, kernels), o prelude vem de core ao inves de std. Ele contem as mesmas traits e enums, mas sem tipos que precisam de alocacao (como String, Vec, Box). Com extern crate alloc, voce pode recuperar esses tipos.


Quando Usar (e Quando Nao Usar)

Use o prelude quando:

  • Estiver escrevendo Rust normalmente — o prelude e injetado automaticamente
  • Quiser criar um prelude customizado para simplificar imports do seu projeto
  • Precisar de TryFrom/TryInto — atualize para edicao 2021+

Nao use explicitamente:

  • Nao adicione use std::prelude::v1::*; manualmente — o compilador ja faz isso
  • Nao tente usar nomes que conflitem com itens do prelude (como Result, Option)

Dica: Se voce esta migrando de edicao e algo para de compilar por ambiguidade de nomes, pode ser que um novo item do prelude conflita com um import existente. Resolva usando caminhos totalmente qualificados.


Veja Tambem