En el día de celebración del décimo aniversario del lanzamiento del lenguaje de programación Rust 1.0 (el proyecto Rust fue fundado en 2006, la versión 0.1 se formó en 2012 y la primera versión estable se propuso en 2015) se publicó el lanzamiento de Rust 1.87. El lenguaje se centra en el manejo seguro de la memoria y proporciona herramientas para lograr un alto paralelismo en la ejecución de tareas, sin utilizar un recolector de basura ni un runtime (el runtime se limita a la inicialización básica y al soporte de la biblioteca estándar).
Los métodos de manejo de memoria en Rust eliminan los errores del desarrollador al manipular punteros y protegen contra problemas que surgen del trabajo de bajo nivel con la memoria, como el acceso a áreas de memoria después de su liberación, desreferenciación de punteros nulos, desbordamientos de búfer, etc. Para la distribución de bibliotecas, la gestión de dependencias y la construcción de proyectos, se está desarrollando el administrador de paquetes Cargo. Para alojar bibliotecas, se soporta el repositorio crates.io.
La seguridad en el manejo de la memoria se garantiza en Rust en tiempo de compilación a través de la verificación de referencias, el seguimiento de la propiedad de los objetos, la gestión de tiempos de vida de objetos (ámbitos) y la evaluación de la corrección del acceso a la memoria durante la ejecución del código. Rust también ofrece herramientas para protegerse contra desbordamientos enteros, requiere la inicialización obligatoria de los valores de las variables antes de su uso, maneja mejor los errores en la biblioteca estándar, aplica el concepto de inmutabilidad de referencias y variables por defecto, y ofrece una fuerte tipificación estática para minimizar errores lógicos.
Novedades principales:
- Se ha añadido soporte para tuberías anónimas (anonymous pipe) en la biblioteca estándar. Para crear tuberías anónimas, se propone el método std::io::pipe(), que puede utilizarse junto con std::process::Command para gestionar los flujos de entrada y salida estándar, así como para combinar los flujos stdout y stderr. use std::process::Command; use std::io::Read; let (mut recv, send) = std::io::pipe()?; let mut command = Command::new(«path/to/bin») // combinar stdout y stderr en una sola tubería .stdout(send.try_clone()?) .stderr(send) .spawn()?; let mut output = Vec::new(); recv.read_to_end(&mut output)?; assert!(command.wait()?.success());
- Se permite la llamada desde código seguro a la mayoría de las funciones integradas en el compilador (Intrinsics) std::arch. El cambio se aplica a las funciones integradas std::arch que están marcadas como inseguras solo debido a la vinculación con funcionalidades específicas, si esa funcionalidad está habilitada. Por ejemplo, _mm256_add_epi32 se puede llamar desde código seguro si la aplicación utiliza ‘#[target_feature(enable = «avx2»)]’.
- Se permite hacer saltos desde bloques «asm!» con código ensamblador a bloques con código en el lenguaje Rust, lo que simplifica el desarrollo de código de bajo nivel, como la implementación de optimizaciones en el núcleo o la organización de la interacción con el hardware. El punto para el salto para el comando ensamblador «jmp» se establece en el macro «asm!» mediante el nuevo operando «label», que contiene una expresión de bloque con código en el lenguaje Rust. unsafe { asm!( «jmp {}», label { println!(«¡Saltó desde asm!»); } ); }
- Se permite especificar con precisión los tipos generales capturados y la duración en las definiciones de rasgos utilizando los tipos de retorno impl Trait. trait Foo { fn method(&'a self) -> impl Sized; type Implicit1: Sized; fn method_desugared(&'a self) -> Self::Implicit1; fn precise(&'a self) -> impl Sized + use; type Implicit2: Sized; fn precise_desugared(&'a self) -> Self::Implicit2; }
- Se ha trasladado un nuevo lote de API a la categoría estable, incluyendo la estabilización de métodos e implementaciones de traits:
- Vec::extract_if
- vec::ExtractIf
- LinkedList::extract_if
- linked_list::ExtractIf
- ::split_off
- ::split_off_mut
- ::split_off_first
- ::split_off_first_mut
- ::split_off_last
- ::split_off_last_mut
- String::extend_from_within
- os_str::Display
- OsString::display
- OsStr::display
- io::pipe
- io::PipeReader
- io::PipeWriter
- impl From for OwnedHandle
- impl From for OwnedHandle
- impl From for Stdio
- impl From for Stdio
- impl From for OwnedFd
- impl From for OwnedFd
- Box<MaybeUninit>::write
- impl TryFrom<Vec> for String
- ::offset_from_unsigned
- ::byte_offset_from_unsigned
- ::offset_from_unsigned
- ::byte_offset_from_unsigned
- NonNull::offset_from_unsigned
- NonNull::byte_offset_from_unsigned
- ::cast_signed
- NonZero::::cast_signed.
- ::cast_unsigned.
- NonZero::::cast_unsigned.
- ::is_multiple_of
- ::unbounded_shl
- ::unbounded_shr
- ::unbounded_shl
- ::unbounded_shr
- ::midpoint
- ::from_utf8
- ::from_utf8_mut
- ::from_utf8_unchecked
- ::from_utf8_unchecked_mut
- El atributo «const» se aplica en las funciones:
- core::str::from_utf8_mut
- ::copy_from_slice
- SocketAddr::set_ip
- SocketAddr::set_port,
- SocketAddrV4::set_ip
- SocketAddrV4::set_port,
- SocketAddrV6::set_ip
- SocketAddrV6::set_port
- SocketAddrV6::set_flowinfo
- SocketAddrV6::set_scope_id
- char::is_digit
- char::is_whitespace
- <N::as_flattened
- <N::as_flattened_mut
- String::into_bytes
- String::as_str
- String::capacity
- String::as_bytes
- String::len
- String::is_empty
- String::as_mut_str
- String::as_mut_vec
- Vec::as_ptr
- Vec::as_slice
- Vec::capacity
- Vec::len
- Vec::is_empty
- Vec::as_mut_slice
- Vec::as_mut_ptr
- Se eliminó el segundo nivel de soporte para la plataforma objetivo i586-pc-windows-msvc. Se recomienda usar la plataforma i686-pc-windows-msvc, que difiere en el soporte de las instrucciones SSE2. La plataforma i586-pc-windows-msvc ha perdido relevancia, ya que para Windows 10 se requiere soporte SSE2, y las versiones anteriores de Windows no son compatibles con Rust.
Fuente: opennet.ru
