extern crate vs use em Rust: como não confundir e escrever corretamente

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

extern crate e use em Rust: qual é o truque e como não pisar em armadilhas

\n\n

Se você já escreveu pelo menos algumas linhas em Rust, certamente já se deparou com as construções extern crate e use. À primeira vista, parece que elas fazem a mesma coisa — conectar código externo. Mas o diabo, como sempre, está nos detalhes. Esta questão está entre as mais populares no Stack Overflow (milhares de visualizações!), e os iniciantes se confundem constantemente com ela. Vamos de uma vez por todas entender a diferença entre extern crate e use, onde cada mágica acontece e como evitar erros típicos.

\n\n

Resumindo: o que é o quê

\n\n

Imagine que seu projeto em Rust é uma casa grande. extern crate é a entrega dos materiais de construção no terreno. Você diz ao compilador: "Ei, esta caixa de tijolos (crate) que quero usar, traga-a". Sem este comando, o compilador nem saberá da existência da biblioteca externa.

\n\n

use é a navegação interna da casa. Você diz: "Quero que a porta desta sala (módulo) leve diretamente à cozinha (tipo ou função específica)". use cria aliases (caminhos curtos) para módulos e tipos já conhecidos, para não precisar escrever o caminho completo toda vez.

\n\n

Simplificando: extern crate responde à pergunta "o que podemos usar?", enquanto use responde à pergunta "como é mais conveniente nos referirmos a isso?".

\n\n

Contexto histórico: por que todos se confundem

\n\n

A confusão não surgiu do nada. Nas versões antigas do Rust (anteriores à edição 2018), extern crate era obrigatório para qualquer crate externo. Ficava assim:

\n\n
// Rust 2015 — estilo antigo\nextern crate serde;\nuse serde::{Serialize, Deserialize};
\n\n

A partir do Rust 2018 edition, o compilador aprendeu a encontrar as dependências do Cargo.toml sozinho. Agora, escrever extern crate para a maioria dos crates não é necessário. Basta adicionar a dependência no Cargo.toml e usar diretamente o use:

\n\n
// Rust 2018+ — novo estilo (extern crate não é obrigatório)\nuse serde::{Serialize, Deserialize};
\n\n

É aí que começa o inferno para os iniciantes. Eles veem exemplos antigos onde extern crate é usado, exemplos novos onde não é, e tentam entender quando ele ainda é necessário. Spoiler: é necessário, mas em casos muito raros.

\n\n

Quando extern crate ainda é necessário (e isso é importante!)

\n\n

Existem três situações em que não se pode evitar o extern crate:

\n\n
    \n
  • Vinculação com bibliotecas do sistema via #[link] — se você está escrevendo bindings para código C/C++ e usando o atributo #[link(name = "sqlite3")], então extern crate é obrigatório.
  • \n
  • Macros globais — alguns crates (por exemplo, log) exportam macros que precisam ser visíveis em todo o programa. No Rust 2018, para isso é necessário escrever extern crate log;.
  • \n
  • Compilação com nomes de crates não padrão — se você usa extern crate my_crate as foo; para renomear um crate.
  • \n
\n\n

Em todos os outros casos, extern crate é um artefato do passado. Mas muitos desenvolvedores, por hábito, continuam a escrevê-lo, e os iniciantes copiam código de tutoriais antigos.

\n\n

Top 5 erros ao trabalhar com extern crate e use

\n\n

Erro nº1: Usar extern crate onde ele não é necessário

\n\n

O problema mais comum. Você adiciona um crate no Cargo.toml, depois escreve extern crate rand; — e o código funciona. Mas é uma linha desnecessária. Em projetos modernos (Rust 2018+), ela apenas polui o código e pode confundir outros desenvolvedores.

\n\n
// Ruim (redundante no Rust 2018+)                

Blogs

Book Recommendations