Foi publicado o lançamento da linguagem de programação de uso geral Rust 1.82, originalmente desenvolvida pelo projeto Mozilla, mas atualmente mantida sob a égide da organização sem fins lucrativos Rust Foundation. A linguagem foca na segurança na manipulação de memória e fornece recursos para alcançar alta paralelização na execução de tarefas, ao mesmo tempo em que não utiliza coletor de lixo nem runtime (runtime se resume à inicialização básica e manutenção da biblioteca padrão).
Os métodos de manipulação de memória em Rust protegem o desenvolvedor de erros ao trabalhar com ponteiros e evitam problemas decorrentes de manipulação de memória de baixo nível, como acesso a áreas de memória após sua liberação, desreferenciação de ponteiros nulos, e estouro de buffer, entre outros. Para distribuição de bibliotecas, construção e gerenciamento de dependências, o projeto conta com o gerenciador de pacotes Cargo. O repositório crates.io é suportado para hospedagem de bibliotecas.
A manipulação segura da memória em Rust é garantida em tempo de compilação através da verificação de referências, rastreamento de propriedade de objetos, controle do tempo de vida dos objetos (escopos) e avaliação da correção do acesso à memória durante a execução do código. Rust também oferece mecanismos para proteção contra estouros inteiros, exige a inicialização obrigatória de valores de variáveis antes do uso, trata erros de forma superior na biblioteca padrão, aplica o conceito de referências e variáveis imutáveis (immutable) por padrão e oferece uma forte tipagem estática para minimizar erros lógicos.
Principais novidades:
- Foi adicionada ao gerenciador de pacotes cargo o comando "info" para exibir informações sobre pacotes no repositório.
- Adicionada a suporte à sintaxe "use<..>" em "impl Trait", que define informações sobre tipos ocultos. Por exemplo, "impl Trait + use<'x, T>" indica que no tipo oculto é permitido usar apenas os parâmetros "x" e "T".
- Foi proposto uma sintaxe separada para criar ponteiros raw, substituindo as macros usadas anteriormente: a macro "addr_of!(expr)" foi substituída pelo operador "&raw const expr", e a macro "addr_of_mut!(expr)" pelo operador "&raw mut expr". struct Packed { not_aligned_field: i32, } fn main() { let p = Packed { not_aligned_field: 1_82 }; // Forma antiga de criar ponteiro raw let ptr = std::ptr::addr_of!(p.not_aligned_field); // Nova forma de criar ponteiro raw let ptr = &raw const p.not_aligned_field; let val = unsafe { ptr.read_unaligned() }; }
- Foi possibilitada a definição de funções e constantes seguras (safe) com tempo de vida 'static' dentro de blocos extern que possuem a qualificação "unsafe" (anteriormente, todos os elementos em "unsafe extern" podiam ter apenas a qualificação "unsafe"): unsafe extern { pub safe static TAU: f64; pub safe fn sqrt(x: f64) -> f64; pub unsafe fn strlen(p: *const u8) -> usize; }
- Os atributos no_mangle, link_section e export_name, que podem levar a comportamentos indefinidos, agora são considerados inseguros e requerem a marcação explícita com o rótulo "unsafe", por exemplo: #[unsafe(no_mangle)] pub fn my_global_function() { }
- Na correspondência de padrões, é permitido ignorar tipos vazios, como "enum Void {}" ou estruturas com um campo vazio visível. use std::convert::Infallible; pub fn unwrap_without_panic<T>(x: Result<T, Infallible>) -> T { let Ok(x) = x; // "Err" pode ser ignorado x }
- Comportamentos padronizados para tipos de números de ponto flutuante (f32 e f64) em relação ao manuseio de valores não numéricos NaN (0.0/0.0) foram estabelecidos, e também foi permitido o uso de operações com ponto flutuante em const fn.
- Em inserções de assembler, é possível usar operandos com o modificador "const" para utilizar valores numéricos inteiros diretamente, sem a necessidade de armazená-los previamente em um registrador. const MSG: &str = "Hello, world!\n"; unsafe { core::arch::asm!( "mov rdx, {LEN} // a instrução 'mov rdx, 14' será formada", LEN = const MSG.len(), … ); }
- A endereçamento de expressões com o modificador "static" é permitido em um contexto seguro, sem a necessidade de definir um bloco unsafe (os operadores "&raw mut" e "&raw const" não afetam o valor do operando, apenas criam um ponteiro para ele): static mut STATIC_MUT: Type = Type::new(); extern "C" { static EXTERN_STATIC: Type; } fn main() { let static_mut_ptr = &raw mut STATIC_MUT; let extern_static_ptr = &raw const EXTERN_STATIC; }
- Uma nova leva de APIs foi traduzida para a categoria estável, incluindo estabilizações de métodos e implementações de traits:
- std::thread::Builder::spawn_unchecked
- std::str::CharIndices::offset
- std::option::Option::is_none_or
- [T]::is_sorted
- [T]::is_sorted_by
- [T]::is_sorted_by_key
- Iterator::is_sorted
- Iterator::is_sorted_by
- Iterator::is_sorted_by_key
- std::future::Ready::into_inner
- std::iter::repeat_n
- impl DoubleEndedIterator for Take
Fonte: opennet.ru
