Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ru/announcements/2024-07-25-Rust-1.80.0.md #138

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions ru/announcements/2024-07-25-Rust-1.80.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
layout: post
title: 'Rust 1.80.0: LazyCell и LazyLock, эксклюзивные паттерны в шаблонах, проверяемые имена и значения cfg'
author: The Rust Release Team
release: 'true'
---

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

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

```console
$ rustup update stable
```

Если у вас ещё не установлен `rustup`, вы можете установить его с [соответствующей страницы](https://www.rust-lang.org/install.html) нашего веб-сайта, а также посмотреть [подробные примечания к выпуску](https://doc.rust-lang.org/nightly/releases.html#version-1800-2024-07-25) на GitHub.

Если вы хотите помочь нам протестировать будущие выпуски, вы можете использовать канал beta (`rustup default beta`) или nightly (`rustup default nightly`). Пожалуйста, [сообщайте](https://github.com/rust-lang/rust/issues/new/choose) обо всех встреченных вами ошибках.

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

### `LazyCell` и `LazyLock`

Это «ленивые» типы, которые откладывают инициализацию своих данных до первого обращения к ним. Они похожи на типы `OnceCell` и `OnceLock`, [стабилизированные в 1.70](https://blog.rust-lang.org/2023/06/01/Rust-1.70.0.html#oncecell-and-oncelock), но с функцией инициализации, включённой в тип. Это завершает стабилизацию в стандартной библиотеке адаптированной функциональности популярных крейтов [`lazy_static`](https://crates.io/crates/lazy-static) и [`once_cell`](https://crates.io/crates/once_cell).

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

```rust
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`](https://doc.rust-lang.org/rustc/check-cfg.html), и теперь Cargo 1.80 включает эти проверки для всех известных ему имён `cfg` (в дополнение ко встроенным в <code>rustc</code>). Сюда входят имена фич из `Cargo.toml`, а также новый вывод `cargo::rustc-check-cfg` из скриптов сборки.

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

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

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

```console
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` автоматически предоставляет [синтаксис](https://doc.rust-lang.org/rustc/check-cfg.html#specifying-expected-names-and-values) для использования их в предупреждениях.

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

Вы можете прочитать больше об этой функциональности [в предыдущей статье блога](https://blog.rust-lang.org/2024/05/06/check-cfg.html), анонсирующей эту функциональность в nightly.

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

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

```rust
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

- [`impl Default для Rc<CStr>`](https://doc.rust-lang.org/stable/alloc/rc/struct.Rc.html#impl-Default-for-Rc%3CCStr%3E)
- [`impl Default для Rc<str>`](https://doc.rust-lang.org/stable/alloc/rc/struct.Rc.html#impl-Default-for-Rc%3Cstr%3E)
- [`impl Default для Rc<[T]>`](https://doc.rust-lang.org/stable/alloc/rc/struct.Rc.html#impl-Default-for-Rc%3C%5BT%5D%3E)
- [`impl Default для Arc<str>`](https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html#impl-Default-for-Arc%3Cstr%3E)
- [`impl Default для Arc<CStr>`](https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html#impl-Default-for-Arc%3CCStr%3E)
- [`impl Default для Arc<[T]>`](https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html#impl-Default-for-Arc%3C%5BT%5D%3E)
- [`impl IntoIterator для Box<[T]>`](https://doc.rust-lang.org/stable/alloc/boxed/struct.Box.html#impl-IntoIterator-for-Box%3C%5BI%5D,+A%3E)
- [`impl FromIterator<String> для Box<str>`](https://doc.rust-lang.org/stable/alloc/boxed/struct.Box.html#impl-FromIterator%3CString%3E-for-Box%3Cstr%3E)
- [`impl FromIterator<char> для Box<str>`](https://doc.rust-lang.org/stable/alloc/boxed/struct.Box.html#impl-FromIterator%3Cchar%3E-for-Box%3Cstr%3E)
- [`LazyCell`](https://doc.rust-lang.org/stable/core/cell/struct.LazyCell.html)
- [`LazyLock`](https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html)
- [`Duration::div_duration_f32`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.div_duration_f32)
- [`Duration::div_duration_f64`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.div_duration_f64)
- [`Option::take_if`](https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.take_if)
- [`Seek::seek_relative`](https://doc.rust-lang.org/stable/std/io/trait.Seek.html#method.seek_relative)
- [`BinaryHeap::as_slice`](https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.as_slice)
- [`NonNull::offset`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.offset)
- [`NonNull::byte_offset`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.byte_offset)
- [`NonNull::add`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.add)
- [`NonNull::byte_add`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.byte_add)
- [`NonNull::sub`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.sub)
- [`NonNull::byte_sub`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.byte_sub)
- [`NonNull::offset_from`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.offset_from)
- [`NonNull::byte_offset_from`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.byte_offset_from)
- [`NonNull::read`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.read)
- [`NonNull::read_volatile`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.read_volatile)
- [`NonNull::read_unaligned`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.read_unaligned)
- [`NonNull::write`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.write)
- [`NonNull::write_volatile`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.write_volatile)
- [`NonNull::write_unaligned`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.write_unaligned)
- [`NonNull::write_bytes`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.write_bytes)
- [`NonNull::copy_to`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.copy_to)
- [`NonNull::copy_to_nonoverlapping`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.copy_to_nonoverlapping)
- [`NonNull::copy_from`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.copy_from)
- [`NonNull::copy_from_nonoverlapping`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.copy_from_nonoverlapping)
- [`NonNull::replace`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.replace)
- [`NonNull::swap`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.swap)
- [`NonNull::drop_in_place`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.drop_in_place)
- [`NonNull::align_offset`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.align_offset)
- [`<[T]>::split_at_checked`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_at_checked)
- [`<[T]>::split_at_mut_checked`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_at_mut_checked)
- [`str::split_at_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_checked)
- [`str::split_at_mut_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut_checked)
- [`str::trim_ascii`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.trim_ascii)
- [`str::trim_ascii_start`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.trim_ascii_start)
- [`str::trim_ascii_end`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.trim_ascii_end)
- [`<[u8]>::trim_ascii`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.trim_ascii)
- [`<[u8]>::trim_ascii_start`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.trim_ascii_start)
- [`<[u8]>::trim_ascii_end`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.trim_ascii_end)
- [`Ipv4Addr::BITS`](https://doc.rust-lang.org/stable/core/net/struct.Ipv4Addr.html#associatedconstant.BITS)
- [`Ipv4Addr::to_bits`](https://doc.rust-lang.org/stable/core/net/struct.Ipv4Addr.html#method.to_bits)
- [`Ipv4Addr::from_bits`](https://doc.rust-lang.org/stable/core/net/struct.Ipv4Addr.html#method.from_bits)
- [`Ipv6Addr::BITS`](https://doc.rust-lang.org/stable/core/net/struct.Ipv6Addr.html#associatedconstant.BITS)
- [`Ipv6Addr::to_bits`](https://doc.rust-lang.org/stable/core/net/struct.Ipv6Addr.html#method.to_bits)
- [`Ipv6Addr::from_bits`](https://doc.rust-lang.org/stable/core/net/struct.Ipv6Addr.html#method.from_bits)
- [`Vec::<[T; N]>::into_flattened`](https://doc.rust-lang.org/stable/alloc/vec/struct.Vec.html#method.into_flattened)
- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.as_flattened)
- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.as_flattened_mut)

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

- [`<[T]>::last_chunk`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.last_chunk)
- [`BinaryHeap::new`](https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.new)

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

Проверьте всё, что изменилось в [Rust](https://github.com/rust-lang/rust/releases/tag/1.80.0), [Cargo](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-180-2024-07-25) и [Clippy](https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-180).

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

Многие люди собрались вместе, чтобы создать Rust 1.80.0. Без вас мы бы не справились. [Спасибо!](https://thanks.rust-lang.org/rust/1.80.0/)
Loading