No dia da celebração do décimo aniversário do lançamento da linguagem de programação Rust 1.0 (o projeto Rust foi fundado em 2006, o lançamento 0.1 foi formado em 2012 e a primeira versão estável foi proposta em 2015), foi divulgado o lançamento do Rust 1.87. A linguagem é focada na segurança no gerenciamento de memória e oferece ferramentas para alcançar alto paralelismo na execução de tarefas, sem a necessidade de um coletor de lixo ou runtime (o runtime se limita à inicialização básica e ao suporte 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:
- A biblioteca padrão agora inclui suporte para canais anônimos (anonymous pipe). Para criar canais anônimos, foi proposto o método std::io::pipe(), que pode ser utilizado em conjunto com std::process::Command para manipular os fluxos de entrada e saída padrão, bem como para combinar os fluxos stdout e stderr. use std::process::Command; use std::io::Read; let (mut recv, send) = std::io::pipe()?; let mut command = Command::new("path/to/bin") // combina stdout e stderr em um único canal .stdout(send.try_clone()?) .stderr(send) .spawn()?; let mut output = Vec::new(); recv.read_to_end(&mut output)?; assert!(command.wait()?.success());
- Foi permitido o chamado a partir de código seguro da maioria das funções internas do compilador (Intrinsics) std::arch. A modificação se aplica a funções internas std::arch que são marcadas como inseguras apenas devido à ligação a alguma funcionalidade específica, se essa funcionalidade estiver habilitada. Por exemplo, _mm256_add_epi32 pode ser chamado a partir de código seguro se o aplicativo usar ‘#[target_feature(enable = "avx2")]’.
- Os blocos "asm!" com código em assembly agora permitem transições para blocos de código em Rust, facilitando o desenvolvimento de código de nível baixo, como a implementação de otimizações no núcleo ou a organização da interação com o hardware. O ponto de transição para o comando de assembly "jmp" é estabelecido no macro "asm!" usando um novo operando "label", que contém uma expressão de bloco com código em Rust. unsafe { asm!( "jmp {}", label { println!("Jumped from asm!"); } ); }
- Permite especificar exatamente os tipos genéricos capturados e sua duração nas definições dos traits usando 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; }
- Uma nova leva de APIs foi traduzida para a categoria estável, incluindo estabilizações de métodos e implementações 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
- O modificador «const» é aplicado em funções:
- 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
- O segundo nível de suporte para a plataforma de destino i586-pc-windows-msvc foi removido. Recomenda-se usar a plataforma i686-pc-windows-msvc, que tem suporte para instruções SSE2. A plataforma i586-pc-windows-msvc tornou-se obsoleta, pois o Windows 10 requer suporte para SSE2, e versões mais antigas do Windows não são mais suportadas no Rust.
Fonte: opennet.ru
