extern crate vs use en Rust: cómo no confundirlos y escribir correctamente

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

extern crate y use en Rust: cuál es el truco y cómo no pisar el rastrillo

\n\n

Si alguna vez has escrito al menos un par de líneas en Rust, seguro que te has topado con las construcciones extern crate y use. A primera vista parece que hacen lo mismo: importar código externo. Pero el diablo, como siempre, está en los detalles. Esta pregunta está entre las más populares en Stack Overflow (¡miles de visitas!), y los principiantes se confunden constantemente. Aclaremos de una vez por todas en qué se diferencia extern crate de use, dónde ocurre cada magia y cómo evitar errores típicos.

\n\n

Brevemente sobre lo principal: qué es qué

\n\n

Imagina que tu proyecto en Rust es una casa grande. extern crate es la entrega de materiales de construcción al terreno. Le dices al compilador: «Oye, esta caja de ladrillos (crate) quiero usarla, tráela». Sin este comando, el compilador ni siquiera sabrá de la existencia de la biblioteca externa.

\n\n

use es la navegación interna dentro de la casa. Dices: «Quiero que la puerta de esta habitación (módulo) lleve directamente a la cocina (tipo o función específica)». use crea alias (rutas cortas) para módulos y tipos ya conocidos, para no tener que escribir la ruta completa cada vez.

\n\n

En pocas palabras: extern crate responde a la pregunta «¿qué podemos usar en absoluto?», mientras que use responde a «¿cómo nos es más cómodo referirnos a ello?».

\n\n

Contexto histórico: por qué todos se confunden

\n\n

La confusión no surgió de la nada. En versiones antiguas de Rust (antes de la edición 2018), extern crate era obligatorio para cualquier crate externo. Se veía así:

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

A partir de Rust 2018 edition, el compilador aprendió a encontrar las dependencias por sí mismo desde Cargo.toml. Ahora, escribir extern crate para la mayoría de los crates no es necesario. Basta con añadir la dependencia en Cargo.toml y usar directamente use:

\n\n
// Rust 2018+ — nuevo estilo (extern crate no es obligatorio)\nuse serde::{Serialize, Deserialize};
\n\n

Aquí es donde empieza el infierno para los principiantes. Ven ejemplos antiguos donde se usa extern crate, ejemplos nuevos donde no aparece, e intentan entender cuándo sigue siendo necesario. Spoiler: es necesario, pero en casos muy raros.

\n\n

Cuándo extern crate sigue siendo necesario (¡y es importante!)

\n\n

Hay tres situaciones en las que no se puede prescindir de extern crate:

\n\n
    \n
  • Enlace con bibliotecas del sistema mediante #[link] — si escribes bindings para código C/C++ y usas el atributo #[link(name = "sqlite3")], entonces extern crate es obligatorio.
  • \n
  • Macros globales — algunos crates (por ejemplo, log) exportan macros que deben ser visibles en todo el programa. En Rust 2018, para esto hay que escribir extern crate log;.
  • \n
  • Compilación con nombres de crate no estándar — si usas extern crate my_crate as foo; para renombrar un crate.
  • \n
\n\n

En todos los demás casos, extern crate es un artefacto del pasado. Pero muchos desarrolladores por costumbre siguen escribiéndolo, y los principiantes copian código de tutoriales antiguos.

\n\n

Top 5 errores al trabajar con extern crate y use

\n\n

Error nº1: Usar extern crate donde no es necesario

\n\n

El problema más frecuente. Añades un crate en Cargo.toml, luego escribes extern crate rand; — y el código funciona. Pero es una línea innecesaria. En proyectos modernos (Rust 2018+) solo ensucia el código y puede confundir a otros desarrolladores.

\n\n
// Mal (redundante en Rust 2018+)\nextern crate rand;\n\n// Bien (solo use es suficiente)\nuse rand::Rng;

Blogs

Book Recommendations