Команда Rust рада сообщить о новой версии языка — 1.80.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.


Если у вас есть предыдущая версия Rust, установленная через rustup, то для обновления до версии 1.80.0 вам достаточно выполнить команду:


$ rustup update stable

Если у вас ещё не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску на GitHub.


Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать канал beta (rustup default beta) или nightly (rustup default nightly). Пожалуйста, сообщайте обо всех встреченных вами ошибках.


Что стабилизировано в 1.80.0


LazyCell и LazyLock


Это «ленивые» типы, которые откладывают инициализацию своих данных до первого обращения к ним. Они похожи на типы OnceCell и OnceLock, стабилизированные в 1.70, но с функцией инициализации, включённой в тип. Это завершает стабилизацию в стандартной библиотеке адаптированной функциональности популярных крейтов lazy_static и once_cell.


LazyLock — потокобезопасный вариант, подходящий для таких мест, как значения static. Так, в примере ниже и поток, ответвившийся с помощью spawn, и основной поток (scope) увидят в точности одну и ту же длительность, поскольку LAZY_TIME будет инициализироваться один раз, в зависимости от того, кто первым получит доступ к статическому значению. При этом ни один из вариантов не требует знать, как именно его инициализировать, как в случае с OnceLock::get_or_init.


use std::sync::LazyLock;
use std::time::Instant;

static LAZY_TIME: LazyLock<Instant> = LazyLock::new(Instant::now);

fn main() {
    let start = Instant::now();
    std::thread::scope(|s| {
        s.spawn(|| {
            println!("Thread lazy time is {:?}", LAZY_TIME.duration_since(start));
        });
        println!("Main lazy time is {:?}", LAZY_TIME.duration_since(start));
    });
}

LazyCell делает то же самое без синхронизации потоков, поэтому он не реализует Sync, необходимый для static, но его можно использовать в статиках thread_local! (с отдельной инициализацией для каждого потока). Любой из этих типов может использоваться и в других структурах данных, в зависимости от потребностей в безопасности потоков, так что ленивая инициализация доступна везде!


Проверяемые имена и значения cfg


В 1.79 rustc стабилизировал флаг --check-cfg, и теперь Cargo 1.80 включает эти проверки для всех известных ему имён cfg (в дополнение ко встроенным в rustc). Сюда входят имена фич из Cargo.toml, а также новый вывод cargo::rustc-check-cfg из скриптов сборки.


О неожиданных конфигурациях сообщает линт unexpected_cfgs, который предназначен для выявления опечаток или других ошибок. Например, в проекте с необязательной зависимостью rayon этот код настроен на неправильное значение:


fn main() {
    println!("Hello, world!");

    #[cfg(feature = "crayon")]
    rayon::join(
        || println!("Hello, Thing One!"),
        || println!("Hello, Thing Two!"),
    );
}

warning: unexpected `cfg` condition value: `crayon`
 --> src/main.rs:4:11
  |
4 |     #[cfg(feature = "crayon")]
  |           ^^^^^^^^^^--------
  |                     |
  |                     help: there is a expected value with a similar name: `"rayon"`
  |
  = note: expected values for `feature` are: `rayon`
  = help: consider adding `crayon` as a feature in `Cargo.toml`
  = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
  = note: `#[warn(unexpected_cfgs)]` on by default

Это предупреждение выдаётся независимо от того, включена или нет фича rayon.


Таблица [lints] в Cargo.toml также может использоваться для расширения списка известных имён и значений для пользовательских cfg. rustc автоматически предоставляет синтаксис для использования их в предупреждениях.


[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(foo, values("bar"))'] }

Вы можете прочитать больше об этой функциональности в предыдущей статье блога, анонсирующей эту функциональность в nightly.


Эксклюзивные диапазоны в шаблонах


В шаблонах диапазонов Rust теперь могут использоваться диапазоны с исключённой конечной точкой («эксклюзивные»), записываемые как a..b или ..b, аналогично типам выражений Range и RangeTo. Например, в следующих шаблонах теперь можно использовать одни и те же константы для конца одного шаблона и начала следующего:


pub fn size_prefix(n: u32) -> &'static str {
    const K: u32 = 10u32.pow(3);
    const M: u32 = 10u32.pow(6);
    const G: u32 = 10u32.pow(9);
    match n {
        ..K => "",
        K..M => "k",
        M..G => "M",
        G.. => "G",
    }
}

Раньше в шаблонах допускались только диапазоны, включающие конечную точку («инклюзивные» — a..=b или ..=b), или открытые (a..) диапазоны. Поэтому код вроде приведённого выше требовал вводить отдельные константы, такие как K - 1 для конечных точек.


Эксклюзивные диапазоны были реализованы в качестве нестабильной фичи уже давно, но стабилизации мешали опасения, что они могут внести путаницу и увеличить вероятность ошибок в шаблонах. В связи с этим были улучшены проверки исчерпывающего сопоставления с шаблоном, чтобы лучше обнаруживать пробелы в сопоставлении, а новые линты non_contiguous_range_endpoints и overlapping_range_endpoints помогут обнаружить случаи, когда вы хотели бы поменять эксклюзивные шаблоны-диапазоны на инклюзивные или наоборот.


Стабилизированные API



Следующие API теперь можно использовать в контексте const:



Прочие изменения


Проверьте всё, что изменилось в Rust, Cargo и Clippy.


Кто работал над 1.80.0


Многие люди собрались вместе, чтобы создать Rust 1.80.0. Без вас мы бы не справились. Спасибо!


От переводчиков


С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов. Если у вас есть вопросы по переводам или хотите помогать с ними, то обращайтесь в чат переводчиков.


Данную статью совместными усилиями перевели andreevlex, TelegaOvoshey, Browning и funkill.

Комментарии (2)


  1. kozlov_de
    28.07.2024 13:06

    Для лиги душноты:

    Это не новинки языка, а библиотеки std


  1. Apoheliy
    28.07.2024 13:06

    Поберегите читателей. Уберите "Системное программирование" - нет тут такого.