Skip to content

Instantly share code, notes, and snippets.

@bakirov
Created December 6, 2018 21:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bakirov/7b4e674683ff2eed23387d5fefca7d9d to your computer and use it in GitHub Desktop.
Save bakirov/7b4e674683ff2eed23387d5fefca7d9d to your computer and use it in GitHub Desktop.
rust2018-lor-edition
Команда Rust рада объявить о выходе новой стабильной версии Rust 1.31.0 и редакции "Rust 2018". Rust -- это язык программирования, который позволяет каждому создавать надежное и эффективное программное обеспечение.
Если у вас установлена предыдущая версия Rust, обновиться до Rust 1.31.0 проще всего следующим образом:
[code=bash]
rustup update stable
[/code]
Если у вас ещё не установлен Rust, то это можно сделать, загрузив с сайта утилиту [inline]rustup[/inline].
[b]Что нового в Rust 1.31.0[/b]
[b]Rust 2018[/b]
Данный релиз ознаменует собой выпуск редакции Rust 2018. Впервые Rust 2018 был упомянут в марте, а затем в июле: прочтите их, чтобы понимать для чего нужен Rust 2018. Также есть статья на сайте Mozilla Hacks.
Вкратце, Rust 2018 это возможность представить всю работу за последние три года в виде цельного пакета. Кроме возможностей языка, сюда входят:
[list]
[*] Инструментарий (поддержка IDE, [inline]rustfmt[/inline], Clippy)
[*] Документация
[*] Работа различных рабочих групп
[*] Новый веб-сайт
[/list]
Для обозначения редакций Rust был представлен ключ [inline]edition[/inline] в [inline]Cargo.toml[/inline]:
[code=bash]
[package]
name = "foo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2018"
[dependencies]
[/code]
Значение 2018 означает, что используется редакция Rust 2018; отсутствие ключа или значение 2015 означает использование редакции Rust 2015.
Важно отметить, что каждый пакет может быть в редакциях 2015 или 2018, и они без проблем могут работать вместе. Проект под редакцией 2018 может использовать зависимости 2015, а проект 2015 использовать зависимости 2018. Это гарантирует целостность экосистемы, сохраняя совместимость существующего кода. Кроме того, существует возможность автоматической миграции кода с редакции Rust 2015 на Rust 2018 при помощи [inline]cargo fix[/inline].
[b]Non-lexical lifetimes (NLL; Нелексические времена жизни)[/b]
В 2018 появились нелексические времена жизни, что на простом языке означает, что проверщик заимствований (borrow checker) стал умнее и теперь не отклоняет правильный код. Например:
[code=rust]
fn main() {
let mut x = 5;
let y = &x;
let z = &mut x;
}
[/code]
В старых версиях этот код выдаст ошибку компиляции:
[code=bash]
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> src/main.rs:5:18
|
4 | let y = &x;
| - immutable borrow occurs here
5 | let z = &mut x;
| ^ mutable borrow occurs here
6 | }
| - immutable borrow ends here
[/code]
из-за того, что время жизни действует внутри лексического блока; то есть, заимствование будет удерживаться за [inline]y[/inline], пока [inline]y[/inline] не покинет пределы main, несмотря на то, что [inline]y[/inline] больше не используется. Код правильный, но проверщик заимствований не мог с ним справиться; сегодня этот код скомпилируется правильно.
Другой пример:
[code=rust]
fn main() {
let mut x = 5;
let y = &x;
let z = &mut x;
println!("y: {}", y);
}
[/code]
Старый Rust выдаст следующую ошибку:
[code=bash]
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> src/main.rs:5:18
|
4 | let y = &x;
| - immutable borrow occurs here
5 | let z = &mut x;
| ^ mutable borrow occurs here
...
8 | }
| - immutable borrow ends here
[/code]
В Rust 2018 вывод ошибки стал лучше:
[code=bash]
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> src/main.rs:5:13
|
4 | let y = &x;
| -- immutable borrow occurs here
5 | let z = &mut x;
| ^^^^^^ mutable borrow occurs here
6 |
7 | println!("y: {}", y);
| - borrow later used here
[/code]
Теперь, вместо того, чтобы показывать место, где [inline]y[/inline] покидает пределы лексического блока, показывается место, где происходят конфликтующие заимствования. Это значительно облегчает отладку подобных ошибок.
[b]Изменения в системе модулей[/b]
Редакция Rust 2018 привносит некоторые изменения в работу с путями, что в конечном итоге привело к упрощению системы модулей.
Вкратце:
[list]
[*] [inline]extern crate[/inline] больше не требуется практически во всех случаях.
[*] Макросы теперь можно импортировать при помощи [inline]use[/inline] вместо атрибута [inline]#[macro_use][/inline].
[*] Абсолютные пути начинаются с названия пакета, где ключевое слово [inline]crate[/inline] ссылается на текущий пакет.
[*] [inline]foo.rs[/inline] и поддиректория [inline]foo/[/inline] могут сосущестовать вместе; [inline]mod.rs[/inline] больше не нужен при размещении подмодулей в поддиректории.
[/list]
Полную информацию можно прочесть в руководстве к редакции.
[b]Упрощенные правила синтаксиса для времени жизни[/b]
В обеих редакциях представлены новые правила синтаксиса для времени жизни для блоков [inline]impl[/inline] и определениях функций. Следующий код:
[code=rust]
impl<'a> Reader for BufReader<'a> {
// methods go here
}
[/code]
теперь может быть написан таким образом:
[code=rust]
impl Reader for BufReader<'_> {
// methods go here
}
[/code]
[inline]'_[/inline] всё ещё подсказывает, что [inline]BufReader[/inline] берёт параметр, но больше нет необходимости создавать имя для него.
В структурах времена жизни всё ещё должны быть определены, но теперь не требуют лишнего кода:
[code=rust]
// Rust 2015
struct Ref<'a, T: 'a> {
field: &'a T
}
// Rust 2018
struct Ref<'a, T> {
field: &'a T
}
[/code]
[inline]: 'a[/inline] добавляется автоматически. При желании, можно продолжать использовать явное определение.
[b][inline]const fn[/inline][/b]
Существует несколько способов определения функции в Rust: регулярная функция с [inline]fn[/inline], небезопасная функция с [inline]unsafe fn[/inline], внешняя функция с [inline]extern fn[/inline]. В этом релизе появился ещё один способ: [inline]const fn[/inline], который выглядит следующим образом:
[code=rust]
const fn foo(x: i32) -> i32 {
x + 1
}
[/code]
Функции [inline]const fn[/inline] могут вызываться как регулярные функции, но вычисляются во время компиляции, а не во время выполнения. Для стабильной работы, они должны иметь детерминированный результат и в настоящее время ограничены следующим минимальным набором операций:
[list]
[*]Арифметические операторы и операторы сравнения с целыми числами
[*]Все логические операторы, кроме [inline]&&[/inline] и [inline]||[/inline]
[*]Построение массивов, структур, перечислений и кортежей
[*]Вызов других функций [inline]const fn[/inline]
[*]Задание индекса массивам и срезам
[*]Доступ к полям структур и кортежей
[*]Чтение из констант
[*][inline]&[/inline] и [inline]*[/inline] на ссылках
[*]Приведение типов, за исключением необработанных указателей на целые числа
[/list]
В будущем данный набор будет расширяться, подробную информацию можно посмотреть здесь.
[b]Новые инструменты[/b]
Наряду с Cargo, Rustdoc, и Rustup, которые являются ключевыми инструментами с версии 1.0, редакция 2018 представляет новое поколоение инструментов: Clippy, Rustfmt, и поддержку IDE.
Clippy является статическим анализатором кода в Rust, достиг версии 1.0 и теперь доступен в стабильной версии Rust. Установку можно произвести следующим образом: [inline]rustup component add clippy[/inline], запуск: [inline]cargo clippy[/inline].
Rustfmt является инструментом для автоматического форматирования кода Rust в соответствии с официальной стилистикой Rust. В этом релизе он достиг версии 1.0; начиная с этой версии гарантируется обратная совместимость для Rustfmt: отформатированный сегодня код останется неизменным в будущем (только с опциями использованными по-умолчанию), и несёт практическую ценность при использовании с системами непрерывной интеграции (CI). Установить Rustfmt можно следующим образом: [inline]rustup component add rustfmt[/inline], использовать: [inline]cargo fmt[/inline].
Поддержка IDE - одна из наиболее востребованных возможностей в Rust. Работы над поддержкой IDE ещё не закончены, но на данный момент уже существуют несколько высококачественных опций:
[b]Tool lints[/b]
В Rust 1.30 были стабилизированы атрибуты инструментов, такие как [inline]#[rustfmt::skip][/inline]. В Rust 1.31 стабилизированы
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment