Prefacio
Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com
Ya conozco el final \ Es la parte que te hace implosionar la cara
They Might Be Giants, "Película experimental" (2004)
Para llegar a dominar un lenguaje, debes escribir muchos programas en ese lenguaje. Recuerdo cuando en 1995 apareció un nuevo lenguaje llamado "JavaScript". Decidí aprenderlo, así que me compré un libro de consulta grande y grueso y me lo leí de cabo a rabo. El libro estaba bien escrito y explicaba minuciosamente el lenguaje con gran detalle, desde las cadenas hasta las listas y los objetos. Pero cuando terminé el libro, seguía sin poder escribir JavaScript para salvar mi vida. Sin aplicar estos conocimientos escribiendo programas, aprendí muy poco. Desde entonces he mejorado en aprender a aprender un lenguaje, que es quizá la habilidad más valiosa que puedes desarrollar como programador. Para mí, eso significa reescribir programas que ya conozco, como el tres en raya.
Rust es ahora el nuevo chico del barrio, y quizás hayas cogido este libro para ver de qué va. Este libro no es una referencia sobre el lenguaje. Esas ya existen, y son bastante buenas. En lugar de eso, he escrito un libro que te reta a escribir muchos pequeños programas que probablemente te resulten familiares. Rust tiene fama de tener una curva de aprendizaje bastante pronunciada, pero creo que este enfoque te ayudará a ser productivo rápidamente con el lenguaje.
En concreto, vas a escribir versiones en Rust de las principales herramientas de línea de comandos de Unix, como head
y cal
. Esto te enseñará más sobre las herramientas y por qué son tan tremendamente útiles, a la vez que te proporcionará el contexto para utilizar conceptos de Rust como cadenas, vectores y filehandles.
Si no estás familiarizado con Unix o con la programación en la línea de comandos, aprenderás conceptos como los valores de salida del programa, los argumentos de la línea de comandos, la redirección de la salida, las tuberías para conectar la salida de un programa (STDOUT
o salida estándar) a la entrada de otro programa (STDIN
o entrada estándar), y cómo utilizar STDERR
(error estándar) para separar los mensajes de error del resto de la salida.
Los programas que escribas revelarán patrones que podrás utilizar cuando crees tus propios programas Rust: patrones como la validación de parámetros, la lectura y escritura de archivos, el análisis sintáctico de texto y el uso de expresiones regulares. Muchas de estas herramientas y conceptos ni siquiera existen en Windows, por lo que los usuarios de esa plataforma crearán versiones decentes de varios programas básicos de Unix.
¿Qué es el óxido (y por qué todo el mundo habla de él)?
Rust es "un lenguaje que capacita a todo el mundo para construir software fiable y eficiente" Rust fue creado por Graydon Hoare y muchos otros alrededor de 2006, mientras Hoare trabajaba en Mozilla Research. Ganó suficiente interés y usuarios como para que en 2010 Mozilla hubiera patrocinado el esfuerzo de desarrollo. En la encuesta 2023 Stack Overflow Developer Survey, más de 90.000 desarrolladores calificaron a Rust como el lenguaje "más querido" por octavo año consecutivo.
El lenguaje es sintácticamente similar a C, por lo que encontrarás cosas como bucles for
, sentencias terminadas en punto y coma y llaves que denotan estructuras de bloques. De forma crucial, Rust puede garantizar la seguridad de la memoria mediante el uso de un verificador de préstamos que rastrea qué parte de un programa tiene acceso seguro a diferentes partes de la memoria.
Sin embargo, esta seguridad no se consigue a expensas del rendimiento. Los programas Rust se compilan en binarios nativos y a menudo igualan o superan la velocidad de los programas escritos en C o C++. Por esta razón, Rust se describe a menudo como un lenguaje de programación de sistemas que ha sido diseñado para el rendimiento y la seguridad.
Rust es un lenguaje de tipado estático, como C/C++ o Java, lo que significa que una variable nunca puede cambiar de tipo, por ejemplo, de un número a una cadena. En Rust no siempre tienes que declarar el tipo de una variable, porque el compilador suele averiguarlo por el contexto. Esto contrasta con los lenguajes de tipado dinámico, como Perl, JavaScript o Python, en los que una variable puede cambiar de tipo en cualquier momento del programa, por ejemplo, de una cadena a un gestor de archivos.
Rust no es un lenguaje orientado a objetos (OO) como C++ o Java, ya que en Rust no hay clases ni herencia. En su lugar, Rust utiliza una struct
(estructura) para representar tipos de datos complejos y rasgos para describir cómo pueden comportarse los tipos. Estas estructuras pueden tener métodos, pueden mutar el estado interno de los datos e incluso pueden llamarse objetos en la documentación, pero no son objetos en el sentido formal de la palabra.
Rust ha tomado prestados muchos conceptos interesantes de otros lenguajes y paradigmas de programación, incluidos lenguajes puramente funcionales como Haskell. Por ejemplo, las variables en Rust son inmutables por defecto, lo que significa que no pueden modificarse respecto a su valor inicial; tienes que informar específicamente al compilador de que son mutables. Las funciones también son valores de primera clase, lo que significa que pueden pasarse como argumentos a otras funciones denominadas de orden superior.
En mi opinión, lo más emocionante es el uso que hace Rust de los tipos enumerados y sumatorios, también llamados tipos de datos algebraicos (ADT), que te permiten representar, por ejemplo, que una función puede devolver un Result
que puede ser tanto un Ok
que contenga algún valor como un Err
que contenga otro tipo de valor. Cualquier código que trate con estos valores debe manejar todas las posibilidades, de modo que nunca corres el riesgo de olvidarte de manejar un error que podría bloquear inesperadamente tu programa.
Quién debería leer este libro
Deberías leer este libro si quieres aprender los fundamentos del lenguaje Rust escribiendo programas prácticos en la línea de comandos que aborden tareas comunes de programación. Imagino que la mayoría de los lectores ya conocerán algunos fundamentos de programación de al menos otro lenguaje. Por ejemplo, probablemente sepan crear variables, utilizar bucles para repetir una acción, crear funciones, etcétera. Imagino que Rust puede ser un primer lenguaje difícil, ya que utiliza tipos de forma extensiva y requiere comprender algunos detalles finos sobre la memoria del ordenador. También asumo que tienes al menos alguna idea de cómo utilizar la línea de comandos y conoces algunos comandos básicos de Unix, como crear, eliminar y cambiar en directorios. Este libro se centrará en el lado práctico de las cosas, mostrándote lo que necesitas saber para hacer las cosas. Dejaré el meollo de la cuestión para libros más completos, como Programming Rust, 2ª ed. , de Jim Bland, Jason Orson y otros, de Jim Blandy, Jason Orendorff y Leonora F. S. Tindall (O'Reilly); The Rust Programming Language, de Steve Klabnik y Carol Nichols (No Starch Press), y Rust In Action, de Tim McNamara (Manning). Te recomiendo encarecidamente que leas uno o varios de ellos junto con este libro para profundizar en el propio lenguaje.
También deberías leer este libro si quieres ver cómo escribir y ejecutar pruebas para comprobar los programas de Rust. Soy partidario de utilizar pruebas no sólo para verificar que los programas funcionan correctamente, sino también como ayuda para dividir un problema en partes pequeñas, comprensibles y comprobables. Demostraré cómo utilizar las pruebas que te he proporcionado, así como cómo utilizar el desarrollo dirigido por pruebas (TDD), en el que primero escribes pruebas y luego escribes código que supere esas pruebas. Espero que este libro demuestre que el rigor del compilador de Rust combinado con las pruebas conduce a mejores programas que son más fáciles de mantener y modificar.
Por qué deberías aprender óxido
Hay muchas razones para aprender Rust. En primer lugar, encuentro que la comprobación de tipos de Rust me impide cometer muchos errores básicos. Mis antecedentes se remontan a lenguajes tipados más dinámicamente, como Perl, Python y JavaScript, en los que la comprobación de tipos es escasa o nula. Cuanto más utilizaba lenguajes tipados estáticamente como Rust, más me daba cuenta de que los lenguajes tipados dinámicamente me obligan a hacer mucho más trabajo, exigiéndome verificar mis programas y escribir muchas más pruebas. Poco a poco llegué a sentir que el compilador de Rust, aunque muy estricto, era mi pareja de baile y no mi enemigo. De acuerdo, es una pareja de baile que te dirá cada vez que le pises los dedos de los pies o te saltes un taco, pero eso al final te convierte en mejor bailarín, que al fin y al cabo es el objetivo. En general, cuando consigo compilar un programa de Rust, suele funcionar como yo pretendía.
En segundo lugar, es fácil compartir un programa Rust con alguien que no conoce Rust o que no es desarrollador en absoluto. Si escribo un programa Python para un compañero de trabajo, debo darle el código fuente de Python para que lo ejecute y asegurarme de que tiene la versión correcta de Python y todos los módulos necesarios para ejecutar mi código. En cambio, los programas Rust se compilan directamente en un archivo ejecutable por la máquina. Puedo escribir y depurar un programa en mi máquina, construir un ejecutable para la arquitectura en la que debe ejecutarse y dar a mi compañero una copia del programa. Suponiendo que tenga la arquitectura correcta, no necesitará instalar Rust y podrá ejecutar el programa directamente.
En tercer lugar, a menudo construyo contenedores utilizando Docker o Singularity para encapsular flujos de trabajo. Me parece que los contenedores para programas Rust son a menudo órdenes de magnitud más pequeños que los de programas Python. Por ejemplo, un contenedor Docker con el tiempo de ejecución de Python puede requerir varios cientos de MB. En cambio, puedo construir una máquina virtual Linux básica con un binario Rust que puede tener un tamaño de sólo decenas de MB. A menos que realmente necesite algunas características particulares de Python, como módulos de aprendizaje automático o deprocesamiento del lenguaje natural, prefiero escribir en Rust y tenercontenedores más pequeños y ligeros.
Por último, encuentro que soy extremadamente productivo con Rust gracias al rico ecosistema de módulos disponibles. He encontrado muchos crates de Rust útiles -que es como se llaman las bibliotecas en Rust- en crates.io, y la documentación en Docs.rs es exhaustiva y fácil de navegar.
Los retos de la codificación
En este libro aprenderás a escribir y probar código Rust creando programas completos. Cada capítulo te mostrará cómo empezar un programa desde cero, añadir funciones, trabajar con mensajes de error y probar tu lógica. No quiero que leas pasivamente este libro en el autobús al trabajo y lo dejes de lado. Aprenderás más escribiendo tus propias soluciones, pero creo que incluso teclear el código fuente que presentote resultará beneficioso.
Los problemas que he seleccionado para este libro proceden de los coreutils de la línea de comandos de Unix, porque supongo que ya resultarán bastante familiares a muchos lectores. Por ejemplo, supongo que habrás utilizado head
y tail
para mirar las primeras o las últimas líneas de un archivo, pero ¿has escrito alguna vez tus propias versiones de estos programas?
Otros Rustceanos (gente que usa Rust) han tenido la misma idea, así que hay muchas otras implementaciones de Rust de estos programas que puedes encontrar en Internet. Aparte de eso, se trata de programas bastante pequeños que se prestan cada uno a enseñar unas cuantas habilidades. He secuenciado los proyectos de modo que se construyan unos sobre otros, así que probablemente sea mejor que trabajes los capítulos en orden.
Una de las razones por las que he elegido muchos de estos programas es que proporcionan una especie de verdad de base. Aunque hay muchos sabores de Unix y muchas implementaciones de estos programas, normalmente todos funcionan igual y producen los mismos resultados. Yo utilizo macOS para mi desarrollo, lo que significa que estoy ejecutando principalmente las variantes BSD (Berkeley Standard Distribution) o GNU (GNU's Not Unix) de estos programas. En general, las versiones BSD son anteriores a las versiones GNU y tienen menos opciones. Para cada programa de desafío, utilizo un script de shell para redirigir la salida del programa original a un archivo de salida. El objetivo es que los programas Rust creen la misma salida para las mismas entradas. He tenido cuidado de incluir archivos codificados en Windows, así como texto ASCII simple mezclado con caracteres Unicode, para obligar a mis programas a tratar con diversas ideas de finales de línea y caracteres de la misma forma que los programas originales.
Para la mayoría de los retos, sólo implementaré un subconjunto de los programas originales, ya que pueden llegar a ser bastante complicados. También he optado por hacer algunos pequeños cambios en la salida de algunos de los programas para que sean más fáciles de enseñar. Considera que esto es como aprender a tocar un instrumento tocando junto con una grabación. No tienes que tocar todas las notas de la versión original. Lo importante es aprender patrones comunes como el manejo de argumentos y la lectura de entradas para que puedas pasar a escribir tu material. Como reto extra, intenta escribir estos programas en otros lenguajes para que puedas ver cómo difieren las soluciones de Rust.
Obtener Rust y el código
Para empezar, tendrás que instalar Rust. Una de mis partes favoritas de Rust es la facilidad de uso de la herramienta rustup
para instalar, actualizar y gestionar Rust. Funciona igual de bien en sistemas operativos (SO) de tipo Windows y Unix, como Linux y macOS. Tendrás que seguir las instrucciones de instalación de tu SO. Si ya has instalado rustup
, puede que quieras ejecutar rustup update
para obtener la última versión del lenguaje y las herramientas, ya que Rust se actualiza aproximadamente cada seis semanas. Ejecuta rustup doc
para leer copiosos volúmenes de documentación. Puedes comprobar tu versión del compilador rustc
con el siguiente comando:
$ rustc --version rustc 1.76.0 (07dca489a 2024-02-04)
Todas las pruebas, datos y soluciones de los programas se encuentran en el repositorio GitHub del libro. Puedes utilizar la herramienta de gestión de código fuente Git (que puede que necesites instalar) para copiarlo a tu máquina. El siguiente comando creará un nuevo directorio en tu ordenador llamado línea de comandos-roya con el contenido del repositorio del libro:
$ git clone https://github.com/kyclark/command-line-rust.git
No debes escribir tu código en el directorio que has clonado en el paso anterior. Debes crear un directorio independiente en otro lugar para tus proyectos. Te sugiero que crees tu propio repositorio Git para guardar los programas que vayas a escribir. Por ejemplo, si utilizas GitHub y lo llamas rust-solutions, puedes utilizar el siguiente comando para clonar tu repositorio. Asegúrate de sustituir YOUR_GITHUB_ID por tu ID real de GitHub:
$ git clone https://github.com/YOUR_GITHUB_ID/rust-solutions.git
Una de las primeras herramientas que encontrarás en Rust es Cargo, que es su herramienta de compilación, gestor de paquetes y ejecutor de pruebas. Cada capítulo te indicará que crees un nuevo proyecto utilizando Cargo, y te recomiendo que lo hagas dentro de tu directorio de soluciones. Copiarás el directorio de pruebas de cada capítulo desde el repositorio del libro a tu directorio de proyecto para probar tu código. Si tienes curiosidad por saber qué aspecto tienen las pruebas de código con Cargo y Rust, puedes ejecutar las pruebas del capítulo 1. Cambia al directorio 01_hello del libro y ejecuta las pruebas con cargo test
:
$ cd command-line-rust/01_hello $ cargo test
Si todo va bien, deberías ver algunas pruebas superadas (sin ningún orden en particular):
running 3 tests test false_not_ok ... ok test true_ok ... ok test runs ... ok
Nota
He probado todos los programas en macOS, Linux, Windows 10/PowerShell y Ubuntu Linux/Subsistema Windows para Linux (WSL). Aunque me encanta lo bien que funciona Rust tanto en sistemas operativos Windows como Unix, dos programas (findr
y lsr
) funcionan de forma ligeramente diferente en Windows debido a algunas diferencias fundamentales del sistema operativo con respecto a los sistemas de tipo Unix. Recomiendo a los usuarios de Windows/PowerShell que se planteen instalar también WSL y trabajar con los programas en ese entorno.
Todo el código de este libro se ha formateado utilizando rustfmt
, que es una práctica herramienta para hacer que tu código tenga un aspecto bonito y legible. Puedes utilizar cargo fmt
para ejecutarlo en todo el código fuente de un proyecto, o puedes integrarlo en tu editor de código para ejecutarlo cuando lo necesites. Por ejemplo, yo prefiero utilizar el editor de texto vim
, que he configurado para que ejecute automáticamente rustfmt
cada vez que guardo mi trabajo. Me parece que así es mucho más fácil leer mi código y encontrar errores.
Te recomiendo que utilices Clippy, un linter para código Rust.Linting consiste en comprobar automáticamente el código en busca de errores comunes, y parece que la mayoría de los lenguajes ofrecen uno o más linters. Tanto rustfmt
como clippy
deberían estar instalados por defecto, pero puedes utilizar rustup component add clippy
si necesitas instalarlo. Luego puedes ejecutar cargo clippy
para que compruebe el código fuente y haga recomendaciones. Si Clippy no emite ningún mensaje, significa que no tiene sugerencias.
Actualización de marzo de 2024
Este libro se publicó originalmente en 2022. El lenguaje Rust y las crates evolucionaron rápidamente en los dos años siguientes, y estoy agradecido a O'Reilly por permitirme actualizar mis ejemplos de código para reflejar estos cambios.He simplificado los programas para que sean más fáciles de enseñar y he mejorado el resultado de las pruebas utilizando la cratepretty_assertions
El mayor cambio, con diferencia, se ha producido en la crate clap
(analizador de argumentos de línea de comandos), que se utiliza en todos los programas a partir del Capítulo 2. La crate clap
estaba en la versión 2.33 cuando escribí el libro y sólo tenía un método (builder) para analizar los argumentos. La versión pasó a la 4 poco después de la publicación e introdujo un segundo método (derive).
Reescribí todos mis programas para utilizar estos nuevos patrones, asegurándome de aislar el análisis sintáctico para que el lector sea libre de sustituirlo por el código que prefiera. Los ejemplos de código de esta versión del libro se pueden encontrar utilizando git checkout
de las ramas clap_v4 y clap_v4_derive para los patrones builder y derive,respectivamente.
¡Ahora estás listo para escribir algo de Óxido!
Convenciones utilizadas en este libro
En este libro se utilizan las siguientes convenciones tipográficas:
- Cursiva
-
Indica nuevos términos, URL, direcciones de correo electrónico, nombres de archivo y extensiones de archivo.
Constant width
-
Se utiliza en los listados de programas, así como dentro de los párrafos para referirse a elementos del programa como nombres de variables o funciones, bases de datos, tipos de datos, variables de entorno, sentencias y palabras clave.
Constant width bold
-
En los bloques de código, a menos que se indique lo contrario, este estilo llama especialmente la atención sobre los elementos que se describen en la discusión que los rodea. En el texto discursivo, destaca los comandos que puede utilizar el lector a medida que avanza.
Constant width italic
-
Muestra el texto que debe sustituirse por valores proporcionados por el usuario o por valores determinados por el contexto.
Consejo
Este elemento significa un consejo o sugerencia.
Nota
Este elemento significa una nota general.
Advertencia
Este elemento indica una advertencia o precaución.
Utilizar ejemplos de código
El material complementario (ejemplos de código, ejercicios, etc.) se puede descargar en https://oreil.ly/commandlinerust_code.
Si tienes una pregunta técnica o un problema al utilizar los ejemplos de código, envía un correo electrónico a bookquestions@oreilly.com.
Este libro está aquí para ayudarte a hacer tu trabajo. En general, si se ofrece código de ejemplo con este libro, puedes utilizarlo en tus programas y documentación. No es necesario que te pongas en contacto con nosotros para pedirnos permiso, a menos que estés reproduciendo una parte importante del código. Por ejemplo, escribir un programa que utilice varios trozos de código de este libro no requiere permiso. Vender o distribuir ejemplos de los libros de O'Reilly sí requiere permiso. Responder a una pregunta citando este libro y el código de ejemplo no requiere permiso. Incorporar una cantidad significativa de código de ejemplo de este libro en la documentación de tu producto sí requierepermiso.
Agradecemos la atribución, pero en general no la exigimos. Una atribución suele incluir el título, el autor, la editorial y el ISBN. Por ejemplo: "Command-Line Rust por Ken Youens-Clark (O'Reilly). Copyright 2022 Charles Kenneth Youens-Clark, 978-1-098-10943-1".
Si crees que el uso que haces de los ejemplos de código no se ajusta al uso legítimo o al permiso concedido anteriormente, no dudes en ponerte en contacto con nosotros en permissions@oreilly.com.
Aprendizaje en línea O'Reilly
Nota
Durante más de 40 años, O'Reilly Media ha proporcionado formación tecnológica y empresarial, conocimientos y perspectivas para ayudar a las empresas a alcanzar el éxito.
Nuestra red única de expertos e innovadores comparten sus conocimientos y experiencia a través de libros, artículos y nuestra plataforma de aprendizaje online. La plataforma de aprendizaje en línea de O'Reilly te ofrece acceso bajo demanda a cursos de formación en directo, rutas de aprendizaje en profundidad, entornos de codificación interactivos y una amplia colección de textos y vídeos de O'Reilly y de más de 200 editoriales. Para más información, visita https://oreilly.com.
Cómo contactar con nosotros
Dirige tus comentarios y preguntas sobre este libro a la editorial:
- O'Reilly Media, Inc.
- 1005 Gravenstein Highway Norte
- Sebastopol, CA 95472
- 800-889-8969 (en Estados Unidos o Canadá)
- 707-827-7019 (internacional o local)
- 707-829-0104 (fax)
- support@oreilly.com
- https://www.oreilly.com/about/contact.html
Tenemos una página web para este libro, donde se enumeran erratas, ejemplos y cualquier información adicional. Puedes acceder a esta página en https://oreil.ly/commandLineRust.
Envía un correo electrónico a bookquestions@oreilly.com para comentar o hacer preguntas técnicas sobre este libro.
Para obtener noticias e información sobre nuestros libros y cursos, visita https://oreilly.com.
Encuéntranos en LinkedIn: https://linkedin.com/company/oreilly-media
Míranos en YouTube: https://www.youtube.com/oreillymedia
Agradecimientos
Mi primera deuda de gratitud es con la comunidad de Rust por crear un lenguaje y un conjunto de recursos para el aprendizaje tan increíbles. Cuando empecé a escribir Rust, aprendí rápidamente que podía intentar escribir un programa ingenuo y dejar que el compilador me dijera lo que tenía que arreglar.
Sumaba o restaba ciegamente &
y *
y clonaba y tomaba prestado hasta que mi programa compilaba, y entonces averiguaba cómo mejorarlo. Cuando me atascaba, invariablemente encontraba ayuda en https://users.rust-lang.org. Todas las personas con las que me he encontrado en Rust, desde Twitter a Reddit, han sido amables y serviciales.
Me gustaría dar las gracias a las comunidades BSD y GNU por los programas y la documentación en los que se basa el proyecto de cada capítulo. Agradezco las generosas licencias que me permiten incluir partes de la documentación de ayuda de susprogramas:
También quiero dar las gracias a mis editores de desarrollo, Corbin Collins y Rita Fernando, y a mis editores de producción, Caitlin Ghegan, Greg Hyman y Kristen Brown. Estoy profundamente en deuda con los revisores técnicos Carol Nichols, Brad Fulton, Erik Nordin y Jeremy Gailor, que me mantuvieron en el buen camino, así como con otras personas que dedicaron su tiempo a hacer comentarios, como Joshua Lynch, Andrew Olson, Jasper Zanjani y William Evans. También debo dar las gracias a mis jefes de los últimos años, la Dra. Bonnie Hurwitz de la Universidad de Arizona y Amanda Borens del Critical Path Institute, que han tolerado el tiempo y el esfuerzo que he dedicado a aprender nuevos lenguajes como Rust en mi trabajo profesional.
En mi vida personal, no podría haber escrito este libro sin el amor y el apoyo de mi mujer, Lori Kindler, y de nuestros tres interesantísimos hijos. Por último, también quiero dar las gracias a mi amigo Brian Castle, que tanto se esforzó en el instituto por redirigir mis gustos musicales del rock duro y progresivo a grupos alternativos como Depeche Mode, The Smiths y They Might Be Giants, de los cuales sólo el último cuajó realmente.
Get Línea de comandos Óxido now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.