El equipo de desarrollo de Rust se complace en anunciar el lanzamiento de una nueva versión de Rust: 1.30.0. Rust es un lenguaje de programación del sistema destinado a la seguridad, la velocidad y la ejecución de código paralelo.
Si tiene una versión anterior de Rust instalada usando rustup
, entonces para actualizar Rust a la versión 1.30.0 solo necesita hacer:
$ rustup update stable
Si aún no ha instalado rustup
, puede instalarlo desde la página correspondiente de nuestro sitio web. Las notas de lanzamiento detalladas para Rust 1.30.0 están disponibles en GitHub.
Lo que se incluye en la versión estable 1.30.0
Rust 1.30 es un lanzamiento sobresaliente con una serie de innovaciones importantes. Pero el lunes, se publicará en el blog oficial una solicitud para verificar la versión beta de Rust 1.31, que será el primer lanzamiento de "Rust 2018". Encontrará más información sobre esto en nuestra publicación anterior "What is Rust 2018" .
Macros procesales
En Rust 1.15, agregamos la capacidad de definir "macros de derivación personalizadas". Por ejemplo, usando serde_derive
, puede declarar:
#[derive(Serialize, Deserialize, Debug)] struct Pet { name: String, }
Y convierta Pet
a JSON y vuelva a estructurar utilizando serde_json
. Esto es posible gracias a la inferencia automática de los Deserialize
Serialize
y Deserialize
utilizando macros de procedimiento en serde_derive
.
Rust 1.30 extiende la funcionalidad de las macros de procedimiento al agregar la capacidad de definir otros dos tipos de macros: "macros de procedimiento de atributos" y "macros de procedimiento funcionales".
Las macros de atributos son similares a las macros de derivación para la salida automática, pero en lugar de generar código solo para el atributo #[derive]
, permiten a los usuarios crear sus propios atributos nuevos. Esto los hace más flexibles: las macros derivadas funcionan solo para estructuras y enumeraciones, pero los atributos se pueden aplicar a otros objetos, como las funciones. Por ejemplo, las macros de atributos le permitirán hacer lo siguiente cuando use un marco web:
#[route(GET, "/")] fn index() {
Este atributo #[route]
se definirá en el marco mismo como una macro de procedimiento. Su firma se verá así:
#[proc_macro_attribute] pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
Aquí tenemos dos parámetros de entrada de tipo TokenStream
: el primero es para el contenido del atributo en sí, es decir, estos son los parámetros GET, "/"
. El segundo es el cuerpo del objeto al que se aplica el atributo. En nuestro caso, este es fn index() {}
y el resto del cuerpo de la función.
Las macros funcionales definen macros cuyo uso se parece a una llamada de función. Por ejemplo, la sql!
:
let sql = sql!(SELECT * FROM posts WHERE id=1);
Esta macro dentro de sí misma analizará las expresiones SQL y verificará su corrección sintáctica. Una macro similar debe declararse de la siguiente manera:
#[proc_macro] pub fn sql(input: TokenStream) -> TokenStream {
Esto es similar a la firma de la macro derivada: obtenemos los tokens que están dentro de los corchetes y devolvemos el código generado por ellos.
Macros y use
Ahora puede importar macros al alcance utilizando la palabra clave use . Por ejemplo, para usar la macro serde-json
paquete serde-json
, la entrada solía ser:
#[macro_use] extern crate serde_json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] });
Y ahora tendrás que escribir:
extern crate serde_json; use serde_json::json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] });
Aquí, la macro se importa, así como otros elementos, por lo que no es necesario usar la anotación macro_use
.
Finalmente, el paquete proc_macro se estabiliza , lo que proporciona la API necesaria para escribir macros de procedimiento. También mejoró significativamente la API de manejo de errores, y paquetes como syn
y quote
ya lo usan. Por ejemplo, antes:
#[derive(Serialize)] struct Demo { ok: String, bad: std::thread::Thread, }
condujo a este error:
error[E0277]: the trait bound `std::thread::Thread: _IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not satisfied --> src/main.rs:3:10 | 3 | #[derive(Serialize)] | ^^^^^^^^^ the trait `_IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not implemented for `std::thread::Thread`
Ahora se emitirá:
error[E0277]: the trait bound `std::thread::Thread: serde::Serialize` is not satisfied --> src/main.rs:7:5 | 7 | bad: std::thread::Thread, | ^^^ the trait `serde::Serialize` is not implemented for `std::thread::Thread`
Mejorando el sistema de módulos
El sistema de módulos ha sido durante mucho tiempo un punto doloroso para los principiantes en Rust; Algunas de sus reglas eran inconvenientes en la práctica. Estos cambios son el primer paso que estamos tomando para simplificar el sistema de módulos.
Además del cambio anterior para macros, hay dos nuevas mejoras para use
. En primer lugar, los paquetes externos ahora se agregan al preludio , es decir:
El problema es que el estilo antiguo no siempre fue necesario debido a las características del sistema de módulos Rust:
extern crate serde_json; fn main() { // ; , `serde_json` // let json = serde_json::from_str("..."); } mod foo { fn bar() { // ; `foo`, `serde_json` // let json = serde_json::from_str("..."); } // - `use` use serde_json; fn baz() { // - `::serde_json`, // , let json = ::serde_json::from_str("..."); } }
Era molesto obtener código roto simplemente moviendo la función a un submódulo. Ahora se comprobará la primera parte de la ruta y, si corresponde a una extern crate
, se utilizará independientemente de la posición de la llamada en la jerarquía del módulo.
Finalmente, el uso comenzó a admitir la importación de elementos en el ámbito actual con rutas que comienzan en cajón :
mod foo { pub fn bar() {
La palabra clave crate
al comienzo de la ruta indica que la ruta comenzará en la raíz del paquete. Anteriormente, las rutas indicadas en la línea de importación de use
siempre se especificaban en relación con la raíz del paquete, pero las rutas en el resto del código que se refieren directamente a los elementos se especificaban en relación con el módulo actual, lo que condujo a un comportamiento inconsistente de las rutas:
mod foo { pub fn bar() {
Tan pronto como el nuevo estilo sea ampliamente utilizado, esperamos aclarar los caminos absolutos sin la necesidad de usar el feo prefijo ::
.
Todos estos cambios juntos simplifican la comprensión de cómo se resuelven los caminos. Donde sea que vea la ruta a::b::c
, a excepción de la declaración de use
, puede preguntar:
- ¿Es un nombre de paquete? Entonces necesitas buscar
b::c
dentro de él. - ¿Es
a
crate
palabras clave? Luego debe buscar b::c
desde la raíz del paquete actual. - De lo contrario, debe buscar a
a::b::c
desde la posición actual en la jerarquía del módulo.
El comportamiento anterior de las rutas en use
, siempre comenzando en la raíz del paquete, sigue siendo aplicable. Pero con una transición única a un nuevo estilo, estas reglas se aplicarán a las rutas en todas partes de manera uniforme, y tendrá que preocuparse mucho menos por las importaciones al mover el código.
Identificadores sin formato
Ahora puede usar palabras clave como identificadores usando la siguiente sintaxis nueva:
Hasta ahora, no hay muchos casos en que esto sea útil para usted. Pero un día intentará usar el paquete para Rust 2015 en un proyecto para Rust 2018 o viceversa, entonces su conjunto de palabras clave será diferente. Hablaremos más sobre esto en el próximo anuncio de Rust 2018.
Aplicaciones sin una biblioteca estándar.
De vuelta en Rust 1.6, anunciamos la estabilización de "no_std" y libcore para crear proyectos sin una biblioteca estándar. Sin embargo, con una aclaración: era posible crear solo bibliotecas, pero no aplicaciones.
En Rust 1.30, puede usar el atributo #[panic_handler]
para implementar de forma independiente el pánico. Esto significa que ahora puede crear aplicaciones, no solo bibliotecas que no usan la biblioteca estándar.
Otros
Una última cosa: en las macros, ahora puede asignar modificadores de alcance , como pub
, utilizando el calificador vis
. Además, los "atributos de herramienta", como #[rustfmt::skip]
, ahora están estabilizados . Verdadero para usar con herramientas de análisis estático , como #[allow(clippy::something)]
, aún no son estables.
Vea las notas de la versión para más detalles.
Estabilización de la biblioteca estándar.
Las siguientes API se han estabilizado en esta versión:
Ipv4Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
Ipv6Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
Iterator::find_map
Además, la biblioteca estándar siempre ha tenido funciones para eliminar espacios en un lado de algún texto, como trim_left
. Sin embargo, para los lenguajes RTL, el significado de "derecha" e "izquierda" aquí lleva a confusión. Por lo tanto, presentamos nuevos nombres para estas funciones:
trim_left
-> trim_start
trim_right
-> trim_end
trim_left_matches
-> trim_start_matches
trim_right_matches
-> trim_end_matches
Planeamos declarar obsoletos los nombres antiguos (pero no eliminarlos, por supuesto) en Rust 1.33.
Vea las notas de la versión para más detalles.
Mejoras de carga
¡La mayor mejora de Cargo en este lanzamiento es que ahora tenemos una barra de progreso!

Vea las notas de la versión para más detalles.
Desarrolladores 1.30.0
Muchas personas juntas crearon Rust 1.30. No podríamos haber completado el trabajo sin cada uno de ustedes. Gracias
De un traductor: Expreso un agradecimiento especial a los miembros de la comunidad Rustycrate y personalmente a Vitvakatu y Virtuos86 por su ayuda con la traducción y revisión.