Skip to content
This repository was archived by the owner on Oct 7, 2022. It is now read-only.

[WIP] Translate blog-post of Rust 1.32 #313

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
5 changes: 3 additions & 2 deletions .yaspellerrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"(не|)валидны(|е|м)",
"автодополнение(|м)",
"автотесты",
"аллокатор(|ы|ов|а|ах)",
"аллокатор(|ы|ов|а|ах|ом)",
"Альхазред",
"антикафе",
"асинхронщина",
Expand Down Expand Up @@ -127,7 +127,7 @@
"потроллить",
"предпросмотр(|ом)",
"приблудины",
"принта",
"принт(а|ом)",
"пробрасывани(е|и)",
"продакшен(|е)",
"промо",
Expand All @@ -136,6 +136,7 @@
"пулл",
"пуш(|ить|им)",
"разыменовывается",
"рантайм(|а)",
"распарсить",
"Раст",
"Растономикон(|а)",
Expand Down
298 changes: 298 additions & 0 deletions _posts/2019-01-17-rust-1.32.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
---
layout: post
categories: новости
title: "Выпуск Rust 1.32"
author: The Rust Release Team
original: https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html
translator: XX
---

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

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

```bash
$ rustup update stable
```

Если у вас еще не установлен `rustup`, вы можете [установить его][install] с соответствующей
страницы нашего веб-сайта. С [подробными примечаниями к выпуску Rust 1.32.0][notes]
можно ознакомиться на GitHub.

> Небольшое замечание: за последнее время вышло несколько новых выпусков `rustup`! Чтобы
> обновить сам `rustup`, выполните `rustup self update`.

[install]: https://www.rust-lang.org/install.html
[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1320-2019-01-17

## Что вошло в стабильную версию 1.32.0

Rust 1.32.0 приобрел несколько упрощающих жизнь улучшений, сменил аллокатор
памяти по умолчанию и сделал больше функций константными. Читайте об
этих изменениях ниже или смотрите подробнее [в примечаниях к выпуску][notes].

<!--cut-->

#### Макрос `dbg`

Начнем с упрощающего жизнь улучшения. Вы используете "отладку принтом"? Если да, и вы
хотите распечатать некоторое значение в процессе работы над кодом, вы вынуждены делать
так:

```rust
let x = 5;

println!("{:?}", x);

// или даже так
println!("{:#?}", x);
```

Это не *самое большое* препятствие, замедляющее разработку, но это требует чересчур много
усилий для простого отладочного вывода значения `x`. Кроме того, тут не учитывается контекст.
Если у вас есть несколько таких `println!`-ов, то становится сложно определить, что к чему
относится в выводе, пока вы сами не добавите информацию о контексте к каждому вызову,
что требует еще больше работы.

Для этих целей в Rust 1.32.0 [мы добавили новый макрос
`dbg!`](https://github.com/rust-lang/rust/pull/56395/):

```rust
fn main() {
let x = 5;

dbg!(x);
}
```

После запуска этой программы, вы увидите:

```text
[src/main.rs:4] x = 5
```

Вместе с именем переменной и ее значением будет выведено название файла и номер
строки, где был совершен вызов `dbg!`.

Кроме того, `println!` печатает в стандартный поток вывода, поэтому лучше использовать
`eprintln!` для печати в стандартный поток ошибок. Макрос `dbg!` выводит в `stderr`,
и это правильно.

Это работает даже в сложных случаях. Рассмотрим пример реализации факториала:

```rust
fn factorial(n: u32) -> u32 {
if n <= 1 {
n
} else {
n * factorial(n - 1)
}
}
```

Для того, чтобы его отладить, мы можем использовать `eprintln!`:

```rust
fn factorial(n: u32) -> u32 {
eprintln!("n: {}", n);

if n <= 1 {
eprintln!("n <= 1");

n
} else {
let n = n * factorial(n - 1);

eprintln!("n: {}", n);

n
}
}
```

Мы хотим выводить `n` на каждой итерации и видеть контекст каждой из веток.
Для `factorial(4)` будет выведено:

```text
n: 4
n: 3
n: 2
n: 1
n <= 1
n: 2
n: 6
n: 24
```

Это приемлемо, но не особенно хорошо. Возможно, мы могли бы поработать над
улучшением вывода информации о контексте, чтобы сделать вывод понятнее. Но
тогда, вместо отладки своего кода, мы будем заниматься улучшением кода отладки.

Рассмотрим тот же пример с использованием `dbg!`:

```rust
fn factorial(n: u32) -> u32 {
if dbg!(n <= 1) {
dbg!(1)
} else {
dbg!(n * factorial(n - 1))
}
}
```

Мы просто обернули макросом каждое из выражений, которое мы хотим вывести. В
результате мы получим:

```text
[src/main.rs:3] n <= 1 = false
[src/main.rs:3] n <= 1 = false
[src/main.rs:3] n <= 1 = false
[src/main.rs:3] n <= 1 = true
[src/main.rs:4] 1 = 1
[src/main.rs:5] n * factorial(n - 1) = 2
[src/main.rs:5] n * factorial(n - 1) = 6
[src/main.rs:5] n * factorial(n - 1) = 24
[src/main.rs:11] factorial(4) = 24
```

Так как макрос `dbg!` возвращает само отлаживаемое значение, в отличии от
`eprintln!`, который возвращает `()`, то нам не нужно делать *никаких*
изменений в структуре нашего кода. Дополнительно мы получаем *гораздо* более
полезный вывод.

Мы уделили много внимания такому маленькому макросу, так как мы надеемся, что
он упростит ваш процесс отладки. Конечно, мы также продолжаем работу над
поддержкой `gdb` и Ко.

#### По умолчанию убран `jemalloc`

Давным-давно у Rust был большой рантайм, подобный Erlang'овому. Для него
был выбран [jemalloc] вместо системного аллокатора, потому что он часто
был производительнее. Постепенно мы все больше и больше избавлялись от
рантайма и в конце-концов он почти весь был удален, но jemalloc остался.
У нас не было способа выбирать пользовательский аллокатор, и поэтому мы
не могли окончательно убрать jemalloc, чтобы не навредить тем, кто нуждался
в нем.

Кроме того, утверждение, что `jemalloc` был всегда аллокатором по умолчанию,
относилось преимущественно к UNIX-миру, так как он был по умолчанию только
на *некоторых* платформах. В частности цель MSVC на Windows уже давно
использует системный аллокатор.

Наконец, хотя jemalloc *обычно* имеет хорошую производительность, это не
всегда так. К тому же он добавляет около 300 килобайт к каждому исполняемому
файлу. Также у нас накопилось множество [других
проблем](https://github.com/rust-lang/rust/issues/36963#issuecomment-252029017)
с jemalloc. И вообще, это странно, что системный язык по умолчанию не использует
системный аллокатор.

По этим причинам, как только [Rust 1.28 предоставил способ выбирать глобальный
аллокатор](https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#whats-in-1.28.0-stable),
мы начали планировать переход на системный аллокатор по умолчанию и предоставление
`jemalloc` в качестве внешней библиотеки. В Rust 1.32 мы наконец завершили эту работу,
и теперь по умолчанию ваша программа будет использовать системный аллокатор.

Если вы хотите продолжать использовать jemalloc, используйте [библиотеку jemallocator].
Для этого в `Cargo.toml` укажите:

```toml
jemallocator = "0.1.8"
```

И в корневом файле вашего проекта:

```rust
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
```

Вот и все! Если вам не нужен jemalloc, вас больше не заставляют его
использовать, но если он вам нужен, то проблема решается несколькими
строчками кода.

[jemalloc]: http://jemalloc.net/
[библиотеку jemallocator]: https://crates.io/crates/jemallocator

#### Заключительные улучшения системы модулей

В последних двух выпусках мы говорили о нескольких улучшениях системы
модулей. В 1.32.0 и редакцию 2018 мы добавили последнее изменение.
Оно называется ["единообразные пути" ("uniform
paths")](https://github.com/rust-lang/rust/pull/56759#issuecomment-450051210)
и разрешает работать с путями импорта также, как с остальными путями,
что до этого работало некорректно. Например:

```rust
enum Color { Red, Green, Blue }

use Color::*;
```

Этот код *ранее* не компилировался, поскольку пути в `use` должны были начинаться
с `super`, `self` или `crate`. Теперь, благодаря поддержке компилятором единообразных
путей, этот код будет работать и сделает то, что вы ожидаете: импорт вариантов
определенного выше перечисления `Color`.

Этим изменением завершается наша ревизия системы модулей. Мы надеемся,
что вы получите удовольствие от работы с упрощенной системой!

#### Улучшения макросов

В Rust 1.32.0 выпущено несколько улучшений макросов. Во-первых, был
добавлен [новый спецификатор фрагмента
`literal`](https://github.com/rust-lang/rust/pull/56072/):

```rust
macro_rules! m {
($lt:literal) => {};
}

fn main() {
m!("some string literal");
}
```

Фрагмент `literal` сопоставляется литералам любого типа: строковым,
числовым и символьным.

В редакции 2018 в макросе `macro_rules` можно использовать также и `?`:

```rust
macro_rules! bar {
($(a)?) => {}
}
```

Фрагменту с `?` будет сопоставлено ноль или одно вхождение, подобно тому,
как фрагменту с `*` уже сопоставляется "ноль или более" вхождений, а с
`+` - "одно или более" вхождений.

### Стабилизация стандартной библиотеки

Макрос `dbg!`, о котором мы уже рассказали выше, стал важным добавлением
к стандартной библиотеке. Помимо этого, 19 функций были сделаны константными
и все числовые примитивные типы получили функции преобразования в
байтовый массив и обратно с указанным порядком байтов. Всего шесть функций
с именами `to_<endian>_bytes` и `from_<endian>_bytes`, где `<endian>` это:

* `ne` - нативный порядок (native endianness)
* `le` - порядок от младшего к старшему (little endian)
* `be` - порядок от старшего к младшему (big endian)

Подробности смотрите [в примечаниях к выпуску][notes].

### Улучшения в Cargo

Cargo получил [псевдоним `cargo c` для команды `cargo
check`](https://github.com/rust-lang/cargo/pull/6218/), и теперь [разрешает
использовать имена пользователей в URL репозиториев](https://github.com/rust-lang/cargo/pull/6242/).

Подробности смотрите [в примечаниях к выпуску][notes].

## Разработчики 1.32.0

Множество людей совместно создавало Rust 1.32.0. Мы не смогли бы
завершить работу без участия каждого из вас. [Спасибо!](https://thanks.rust-lang.org/rust/1.32.0)