Liberação Rust 1.36.0: característica futura, estabilização de alocação e MaybeUninit

Apresento a você uma tradução da publicação sobre a nova versão da linguagem de programação favorita de todos, Rust .


1. Introdução


A equipe da linguagem de programação Rust tem o prazer de anunciar uma nova versão, 1.36.0. Rust é uma linguagem de programação que permite a todos desenvolver software rápido e confiável.


Se você instalou a versão anterior do Rust usando rustup , obter a versão atual não será difícil:


 $ rustup update stable 

Se você ainda não possui rustup , pode obtê-lo na página correspondente em nosso site. Uma revisão detalhada desta versão está disponível no GitHub.


O que está incluído na versão estável?


Esta versão fez muitas mudanças, incluindo a estabilização da tão esperada característica do Future , alloc MaybeUninit<T> , estrutura MaybeUninit<T> , NLL Rust 2015 , uma nova implementação do HashMap<K, V> e suporte para o sinalizador --offline no Cargo.


As mudanças mais significativas estão descritas abaixo, no entanto, você também pode ver uma lista detalhada de inovações para obter mais conscientização.


Estabilização futura


O Rust 1.36.0 estabilizou a tão esperada Future !


Esperamos que essa inovação permita que caixas populares, bibliotecas e todo o ecossistema se preparem para a .await async / .await , que está planejada para ser estabilizada em um futuro próximo.


Estabilização do rack Distrib


Antes da versão 1.36.0, a biblioteca padrão consistia em proc_macro std , core e proc_macro . O core tinha funcionalidade básica (como Iterator e Copy ) e poderia ser usado em ambientes com #![no_std] , pois não impunha nenhum requisito. Enquanto isso, o std crate fornecia tipos como Box<T> , além da funcionalidade do sistema operacional (alocador global).


A partir do Rust 1.36.0, os componentes da caixa std , dependentes do alocador global, por exemplo, Vec<T> , agora estão disponíveis na alloc alocação. Enquanto isso, a std está reexportando esses componentes.


Enquanto os programas #![no_std] usando a caixa de alloc ainda exigem o canal nightly , as #![no_std] c #![no_std] podem usar a alloc no Rust estável.


Também observamos que todos os programas "regulares" (sem #![no_std] ) em suas dependências podem conter as bibliotecas descritas acima com #![no_std] . Esperamos que isso ajude a desenvolver um ecossistema compatível com #![no_std] .


Se você é desenvolvedor de uma biblioteca que requer que primitivas de alocação funcionem, recomendamos que marque sua biblioteca como compatível com #![no_std] usando a seguinte sintaxe no início do arquivo lib.rs :


 #![no_std] extern crate alloc; use alloc::vec::Vec; 

MaybeUninit place mem :: uninitialized


Nas versões anteriores do Rust, a função mem::uninitialized permitia o cancelamento das verificações de inicialização, porque pensava que você JÁ havia inicializado para digitar T sem fazer nada. Um dos usos dessa função foi a alocação "lenta" de matrizes.


No entanto, mem::uninitalized é uma operação excessivamente perigosa que não pode ser usada corretamente com o compilador Rust, assumindo que todos os valores foram inicializados corretamente.


Por exemplo, chamar mem::uninitialized::<bool>() causará imediatamente um comportamento indefinido , pois, do ponto de vista do Rust, os bits não inicializados são zero ( false ) ou unidade ( true ), e apenas dois dos padrões acima são adequados para o tipo de bool .


Para resolver essa situação, o tipo MaybeUninit<T> foi estabilizado no Rust 1.36.0. O compilador Rust não assume mais que MaybeUninit<T> é um tipo inicializado de T Dessa forma, você pode executar uma inicialização gradual com mais segurança e, finalmente, usar .assume_init() quando tiver certeza de que maybe_t: MaybeUninit<T> contém o tipo inicializado T


Como MaybeUninit<T> é uma alternativa mais segura a partir do Rust 1.38, a função mem::uninitialized ficará obsoleta.


Para saber mais sobre memória não inicializada, mem::uninitialized e MaybeUninit<T> , leia o artigo de Alexis Bessessner . A biblioteca padrão também contém documentação suficiente sobre MaybeUninit<T> .


NLL for Rust 2015


No anúncio do Rust 1.31.0, falamos sobre o NLL (cronogramas de vida não lexical), uma inovação na linguagem que torna o controlador de link (verificador de empréstimo) mais inteligente e amigável. Por exemplo, agora você pode escrever assim:


 fn main() { let mut x = 5; let y = &x; let z = &mut x; //     1.31.0 } 

Em 1.31.0, a NLL estava estabilizada apenas para o Rust 2018 e supunha-se que o transferiríamos para o Rust 2015 no futuro. Isso foi feito no Rust 1.36.0, a NLL ficou disponível para o Rust 2015.


Com o NLL suportado nas duas versões, estamos nos aproximando da remoção do antigo controlador de link. No entanto, o antigo controlador de link, infelizmente, aceitou o código incorreto , que NÃO deveria ter aceito.


E, como resultado, a NLL está agora no estágio de “migração”, no qual emitiremos avisos em vez de erros se o controlador de link NLL não aprovar o código que aprovaria o antigo controlador de link baseado em AST . Aconselhamos que você verifique a lista de caixas públicas afetadas .


Para saber mais sobre a NLL, MIR, como corrigir problemas de integridade relacionados e o que pode ser feito com os avisos do compilador que aparecem, leia o artigo de Felix Klok .


Nova implementação do HashMap


No Rust 1.36.0, a implementação anterior do HashMap<K, V> foi substituída por uma hashbrown hashbrown com base no design da SwissTable . A interface permanece a mesma, mas a implementação atual é, em média, mais rápida e consome menos memória. No entanto, observe que a implementação padrão ainda usa o algoritmo SipHash 1-3 .


- Suporte offline em Carga


Durante a maioria das compilações, o Cargo não usa sua rede. No entanto, em alguns momentos, por exemplo, quando uma nova dependência foi adicionada, o Cargo ainda tentará acessar a rede. Às vezes, esse comportamento é inaceitável (em um sistema isolado ou em um avião).


O Rust 1.36.0 estabilizou a nova bandeira - --offline . Esse sinalizador substitui o algoritmo de resolução de dependência, em vez de usar dependências em cache locais.


Se as caixas solicitadas não estiverem disponíveis sem uma rede desconectada, o Cargo sairá com um erro. Para preencher previamente o cache local antes de sair da rede, use o comando cargo fetch , que carrega todas as dependências necessárias para um projeto específico.


Para saber mais sobre --offline e cargo fetch , leia o artigo de Nick Cameron . Outras alterações no Cargo são descritas em detalhes aqui .


Alterações na biblioteca



Outras mudanças


Descrições detalhadas de alterações na versão 1.36.0 estão disponíveis para o Rust , a biblioteca padrão , Cargo e Clippy .


Membros 1.36.0


Muitas pessoas se uniram para criar o Rust 1.36.0. Não poderíamos ter feito isso sem todos vocês, obrigado !


Do tradutor


Em caso de dúvidas sobre o idioma Rust, eles poderão ajudá-lo no bate-papo do telegrama no idioma russo ou em um bate-papo semelhante para os recém-chegados .


Source: https://habr.com/ru/post/pt458848/


All Articles