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:
| Trait | Modulo | O Que Faz |
|---|---|---|
Copy | std::marker | Marca tipos copiaveis bit-a-bit |
Send | std::marker | Marca tipos transferiveis entre threads |
Sync | std::marker | Marca tipos compartilhaveis entre threads |
Sized | std::marker | Marca tipos com tamanho conhecido |
Unpin | std::marker | Marca tipos moviveis dentro de Pin |
Drop | std::ops | Destrutor customizado |
Fn | std::ops | Closure chamavel por referencia |
FnMut | std::ops | Closure chamavel por referencia mutavel |
FnOnce | std::ops | Closure chamavel uma vez (consome) |
Clone | std::clone | Duplicacao explicita |
PartialEq | std::cmp | Comparacao de igualdade parcial |
Eq | std::cmp | Comparacao de igualdade total |
PartialOrd | std::cmp | Ordenacao parcial |
Ord | std::cmp | Ordenacao total |
AsRef | std::convert | Conversao barata por referencia |
AsMut | std::convert | Conversao barata por referencia mutavel |
Into | std::convert | Conversao infalivel (consumindo) |
From | std::convert | Conversao infalivel (construindo) |
Default | std::default | Valor padrao |
Iterator | std::iter | Iteracao |
Extend | std::iter | Estender colecao a partir de iterador |
IntoIterator | std::iter | Conversao para iterador |
DoubleEndedIterator | std::iter | Iteracao bidirecional |
ExactSizeIterator | std::iter | Iterador com tamanho exato |
Option (e Some/None) | std::option | Valor opcional |
Result (e Ok/Err) | std::result | Resultado falivel |
Tipos e Funcoes Importados
| Item | Modulo | O Que E |
|---|---|---|
Box<T> | std::boxed | Alocacao no heap |
String | std::string | Texto UTF-8 no heap |
ToString (trait) | std::string | Conversao para String |
Vec<T> | std::vec | Vetor dinamico |
Option<T> | std::option | Valor opcional |
Result<T, E> | std::result | Resultado falivel |
Some, None | std::option | Variantes de Option |
Ok, Err | std::result | Variantes de Result |
drop() | std::mem | Funcao para descartar um valor |
Adicionados na Edicao 2021
A edicao 2021 adicionou ao prelude:
| Item | Modulo | O Que Faz |
|---|---|---|
TryFrom | std::convert | Conversao falivel |
TryInto | std::convert | Conversao falivel |
FromIterator | std::iter | Construir colecao a partir de iterador |
Adicionados na Edicao 2024
A edicao 2024 adicionou:
| Item | Modulo | O Que Faz |
|---|---|---|
Future | std::future | Trait base para async |
IntoFuture | std::future | Conversao 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
- Sistema de Modulos do Rust — como use, mod e pub funcionam
- Modulo std::convert — From, Into, TryFrom que estao no prelude
- Modulo std::marker — Copy, Send, Sync, Sized que estao no prelude
- Visao Geral de std::collections — colecoes que NAO estao no prelude
- String e &str — String e ToString que estao no prelude
- Documentacao oficial — std::prelude