Rust | ||
---|---|---|
Desarrollador(es) | ||
Rust Project https://www.rust-lang.org/ | ||
Información general | ||
Extensiones comunes |
.rs .rlib | |
Paradigma | multiparadigma, imperativo, orientado a objetos, procedural, concurrente, funcional, compilado, propósito general | |
Apareció en | 2010 | |
Diseñado por | Graydon Hoare | |
Última versión estable | 1.79.0[1] (13 de junio de 2024 (5 meses y 11 días)) | |
Sistema de tipos | estático, fuerte, inferido, estructural | |
Influido por | Alef, C#, C++, Camlp4, Common Lisp, Cyclone, Erlang, Haskell, Hermes, Limbo, Napier, Napier88, Newsqueak, NIL, Ruby, Sather, Standard ML, Ocaml, Racket, Swift | |
Ha influido a | C#, Elm, Idris, Swift | |
Sistema operativo | Linux, macOS, Windows, FreeBSD, OpenBSD,[2] Redox, Android, iOS[3] | |
Licencia | Licencia Apache 2.0 o Licencia MIT[4] | |
Rust es un lenguaje de programación compilado, de propósito general y multiparadigma (aunque no soporta las características de los mismos en su totalidad) que está siendo desarrollado por Fundación Rust. Es un lenguaje de programación multiparadigmático que soporta programación funcional pura, por procedimientos, imperativa y orientada a objetos.
Según la política de Mozilla,[5] Rust es desarrollado de forma totalmente abierta y busca la opinión y contribución de la comunidad. El diseño del lenguaje se ha ido perfeccionando a través de las experiencias en el desarrollo del motor de navegador Servo,[6] y el propio compilador de Rust. Aunque es desarrollado y patrocinado por Mozilla y Samsung, es un proyecto comunitario. Una gran parte de las contribuciones proceden de los miembros de la comunidad.[7]
Para el 2020 es uno de los lenguajes de programación más usados a la hora de trabajar con criptomonedas y crear nodos para minar criptoactivos.[8] En 2022, Rust se convirtió en el tercer lenguaje de programación usado en el núcleo Linux, después de C y ensamblador.[9]
El objetivo de Rust es ser un buen lenguaje para la creación de grandes programas del lado del cliente y del servidor que se ejecuten en Internet. Esto ha llevado a un conjunto de características con un énfasis en la seguridad, el control de distribución de la memoria y la concurrencia. Se espera que el rendimiento de código seguro sea más lento que C++, si el rendimiento es la única consideración, pero si lo comparamos con el código C++ hecho para que tome precauciones comparables a las que toma Rust, este último puede ser incluso más rápido.[10]
La sintaxis de Rust es similar a la de C y C++, con bloques de código delimitados por llaves y estructuras de control de flujo tales como if
, else
, do
, while
y for
. No todas las estructuras de C y C++ están presentes, además, otras (como la palabra clave match
para ramificación multidireccional) serán menos familiares para programadores que vienen de estos lenguajes.
El sistema está diseñado para tener un acceso seguro a la memoria, y no permite punteros nulos o punteros colgantes.[11][12] Los valores de los datos sólo se pueden inicializar a través de un conjunto fijo de formas, las cuales requieren que sus entradas hayan sido ya inicializadas.[13]
El sistema de tipos soporta un mecanismo similar a las clases de tipos, llamado "traits", inspirados directamente por el lenguaje Haskell. Esta es una facilidad para el polimorfismo que soporta distintos tipos de argumentos (polimorfismo ad-hoc), lograda mediante la adición de restricciones para escribir declaraciones de variables. Otras características de Haskell, como el polimorfismo de diferente tipo (higher-kinded), no están soportadas.
Rust cuenta con inferencia de tipos, para las variables declaradas con la palabra clave let. Tales variables no requieren ser inicializadas con un valor asignado con el fin de determinar su tipo. A tiempo de compilación produce un error si cualquier rama de código falla al asignar un valor a la variable.[14] Las funciones pueden recibir parámetros genéricos pero deben ser delimitados expresamente por los traits, no hay manera de dejar fuera de declaraciones de tipo sin dejar de hacer uso de los métodos y operadores de los parámetros.
La concurrencia es soportada a través de tareas simples, similares a los encontrados en Erlang y otros lenguajes basado en actores. En dichos sistemas, las tareas se comunican a través del paso de mensajes, en lugar de compartir los datos directamente. Por motivos de rendimiento, es posible enviar datos sin copiar, usar cajas únicas. Las cajas únicas son la garantía de tener un solo propietario, y puede ser liberada por la tarea de enviar para su uso por el receptor.
El sistema de objetos de Rust se basa en implementaciones, traits y tipos estructurados. Las implementaciones cumplen una función similar a la de las clases en otros lenguajes, y se definen con la palabra clave impl. Herencia y polimorfismo son proporcionados por los traits, permiten que los métodos se definan y se mezclen en las implementaciones. Los tipos estructurados se utilizan para definir los campos. Implementaciones y rasgos no pueden definir los campos propios, y sólo los traits proporcionar herencia, con el fin de evitar el problema del diamante de C++.
El lenguaje surgió a partir de un proyecto personal iniciado en 2006 por el empleado de Mozilla, Graydon Hoare,[15] quien afirmó que el proyecto posiblemente recibió su nombre de la familia de hongos de la roya.[16] Mozilla comenzó a patrocinar el proyecto en 2009[15] y lo anunció en 2010.[17][18] El mismo año, el trabajo pasó del compilador inicial (escrito en OCaml) al compilador autohospedado escrito en Rust.[19] Denominado rustc, se compiló con éxito en 2011.[20] rustc usa LLVM como su back end.
La primera versión pre-alfa numerada del compilador de Rust se produjo en enero de 2012.[21] Rust 1.0, la primera versión estable, se publicó el 15 de mayo de 2015.[22][23] Después de 1.0, las versiones de puntos estables se entregan cada seis semanas, mientras que las funciones se desarrollan en Rust todas las noches y luego se prueban con versiones alfa y beta que duran seis semanas.[24]
Junto con la escritura estática convencional, antes de la versión 0.4, Rust también admitía typestates. El sistema typestate modeló aserciones antes y después de las sentencias del programa, mediante el uso de una checksentencia especial. Las discrepancias se pueden descubrir en el momento de la compilación, en lugar de cuando se ejecuta un programa, como podría ser el caso de las aserciones en código C o C ++. El concepto typestate no era exclusivo de Rust, ya que se introdujo por primera vez en el lenguaje NIL.[25] Los typestates se eliminaron porque en la práctica se usaban poco, aunque la misma función aún se puede lograr con un patrón de marca.[26]
El estilo del sistema de objetos cambió considerablemente en las versiones 0.2, 0.3 y 0.4 de Rust. La versión 0.2 introdujo clases por primera vez, y la versión 0.3 agregó varias características, incluidos destructores y polimorfismo mediante el uso de interfaces. En Rust 0.4, se agregaron rasgos como un medio para proporcionar herencia; las interfaces se unificaron con rasgos y se eliminaron como una característica separada. Las clases también se eliminaron, reemplazadas por una combinación de implementaciones y tipos estructurados.
Comenzando en Rust 0.9 y terminando en Rust 0.11, Rust tenía dos tipos de punteros incorporados: ~y @, simplificando el modelo de memoria central. Reimplementó esos tipos de puntero en la biblioteca estándar como Boxy (ahora eliminado) Gc.
En enero de 2014, antes de la primera versión estable, Rust 1.0, el editor en jefe de Dr. Dobb's, Andrew Binstock, comentó sobre las posibilidades de Rust de convertirse en un competidor de C ++ y de los otros lenguajes próximos D, Go y Nim (entonces Nimrod). Según Binstock, mientras que Rust era "ampliamente visto como un lenguaje notablemente elegante", la adopción se ralentizó porque cambió repetidamente entre versiones.[27]
Rust fue el tercer lenguaje de programación más querido en la encuesta anual de Stack Overflow de 2015[28] y ocupó el primer lugar en 2016-2020.[29][30][31][32][33]
El lenguaje se menciona en El libro de Mozilla como "metal oxidado".[34]
En agosto de 2020, Mozilla despidió a 250 de sus 1000 empleados en todo el mundo como parte de una reestructuración corporativa provocada por el impacto a largo plazo de la pandemia de COVID-19. El equipo detrás de Servo, un motor de navegador escrito en Rust, se disolvió por completo. El evento generó preocupaciones sobre el futuro de Rust, ya que algunos miembros del equipo eran colaboradores activos de Rust.
A la semana siguiente, el equipo central de Rust reconoció el grave impacto de los despidos y anunció que los planes para una fundación de Rust estaban en marcha. El primer objetivo de la fundación sería tomar posesión de todas las marcas comerciales y nombres de dominio, y asumir la responsabilidad financiera por sus costos.[35]
El 8 de febrero de 2021, sus cinco empresas fundadoras (AWS, Huawei, Google, Microsoft y Mozilla) anunciaron la formación de la Fundación Rust.[36][37]
El 6 de abril de 2021, Google anunció la compatibilidad con Rust dentro del Proyecto de código abierto de Android como alternativa a C/C++.[38]
El siguiente código es válido para Rust 1.70.0. En versiones posteriores puede cambiar la sintaxis o las funciones.
Programa que muestra la frase “¡Hola, mundo!”:
fn main() {
println!("¡Hola, mundo!");
}
Dos versiones de la función factorial, en el estilo recursivo e iterativo:
/* Las ramas en esta función exhiben los valores de retorno implícito opcional
de Rust, que pueden ser usados cuando se prefiera un estilo más “funcional”.
A diferencia de C++ y otros lenguajes similares, la estructura de control
`if` es una expresión en vez de una declaración, por tanto, tiene un valor
de retorno propio. */
fn recursive_factorial(n: i32) -> i32 {
if n == 0 {
1
} else {
n * recursive_factorial(n-1)
}
}
fn iterative_factorial(n: i32) -> i32 {
// Las variables son declaradas con `let`.
// La palabra `mut` permite que las variables puedan ser mutadas.
let mut i = 1;
let mut result = 1;
while i <= n {
result *= i;
i += 1;
}
return result; // Un retorno explícito, en contraste con la función previa.
}
fn main() {
println!("Resultado recursivo: {}", recursive_factorial(10));
println!("Resultado iterativo: {}", iterative_factorial(10));
}
Una simple demostración de las capacidades de concurrencia ligera de Rust:
/* Esta función crea diez “tareas” que se pueden ejecutar concurrentemente.
Ejecútalo múltiples veces y observa la salida irregular que se obtiene al
estar cada tarea llamando al stdout, ya que cada tarea puede producirse entre
las sucesivas llamadas a `println` y dentro de la función `println` en sí. */
use std::thread;
fn main() {
// Esta cadena es inmutable, para que pueda ser accedida de forma segura
// por múltiples tareas.
let message = "¡Miradme, soy un proceso ligero!";
// Los bucles `for` funcionan con cualquier tipo que implemente el trait
// `Iterator`.
for num in 0..10 {
// Es muy probable que no muestre los 10 mensajes porque si la “tarea”
// principal termina antes, las “tareas” producidos ya no se ejecutan.
thread::spawn (move || {
println!("{}", message);
// `println!` es una macro que verifica estáticamente un string de
// formato. Las macros son estructurales (como en Scheme) en lugar
// de ser textuales (como en C).
println!("Este mensaje ha sido ofrecido por la tarea {}.", num);
});
}
}
Además de los tipos estáticos convencionales, Rust también incluyó typestates hasta su versión 0.4. El sistema typestate modela afirmaciones antes y después de las declaraciones del programa, mediante el uso de una declaración de verificación especial. Las discrepancias pueden ser descubiertas durante la compilación, en lugar de una vez que el programa se ejecuta, como podría ser el caso de las aserciones en el código C o C++. El concepto typestate no es exclusivo de Rust, ya que se introdujo por primera vez en el lenguaje de programación NIL.[25] Fueron retirados los typestates porque en la práctica se encontraron poco usados, sin embargo la misma funcionalidad aún se puede lograr con los patrones del mismo lenguaje.[39]
El estilo del sistema de objetos ha cambiado considerablemente en las versiones 0.2, 0.3 y 0.4 de Rust. La versión 0.2 introdujo clases por primera vez, con la versión 0.3 añadiendo un número de características que incluyen destructores y polimorfismo mediante el uso de interfaces. En Rust 0.4, se añadieron traits como un medio para proporcionar herencia, las interfaces se unificaron con los traits y eliminándose como una característica independiente. También se eliminaron las clases, reemplazadas por una combinación de las implementaciones y tipos estructurados.
Rust permite la creación de interfaces gráficas mediante las APIs nativas de la plataforma anfitriona, esto gracias a que tiene características de un lenguaje de bajo nivel. Sin embargo, esta ruta de desarrollo puede llegar a generar dificultades en proyectos que planten la admision de múltiples plataformas.[40]
Actualmente existen múltiples desarrollos para crear GUIs en Rust, algunos permiten la creación de la interfaz junto a Electron o haciendo uso de HTML, algunos otros, suministran bibliotecas nativas para el lenguaje, pero todavía se encuentran en un estado inmaduro de desarrollo. Finalmente están los proyectos que enlazan bibliotecas bastante conocidas y con una mayor madurez en su desarrollo, como GTK o Qt, lo cuales permiten desarrollos multiplataforma.[41] Algunos proyectos populares son los siguientes:
Es una implementación de las bibliotecas de GTK para el uso junto al lenguaje Rust. Para ello, crea funciones de Rust superpuestas a las funciones de las bibliotecas de GTK en C, haciendo uso de Foreign Function Interface que ofrece Rust.
Biblioteca de bajo nivel que hace uso de OpenGL o Vulkan.
Se están escribiendo en Rust un navegador web y varios componentes relacionados, que incluyen:
Muchos sistemas operativos (SO) y componentes relacionados se están escribiendo en Rust. A partir de enero de 2019, los sistemas operativos incluían: BlogOS, intermezzOS, QuiltOS, Redox, RustOS, Rux, Tefflin y Tock.
auto_ptr
or the C++0x unique_ptr
), and reference counting via shared_ptr
or COM. One of the goals of Rust’s type system is to support these patterns exactly as C++ does, but to enforce their safe usage. In this way, the goal is to be competitive with the vast majority of idiomatic C++ in performance, while remaining memory-safe…».
<ref>
definida en las <references>
con nombre «lambda rust» no se utiliza en el texto anterior.