LINUX.ORG.RU

Rust 1.31.0 (2018)

 ,


5

9

Команда Rust объявила о выходе новой стабильной версии Rust 1.31.0, который ознаменует собой также выход новой редакции «Rust 2018». Rust — это язык программирования, который позволяет каждому создавать надежное и эффективное программное обеспечение.

Если у вас установлена предыдущая версия Rust, обновиться до Rust 1.31.0 проще всего следующим образом:

rustup update stable

Если у вас ещё не установлен Rust, то это можно сделать, загрузив с сайта утилиту rustup.

Что нового в Rust 1.31.0

Rust 2018

Данный релиз ознаменует собой выпуск редакции Rust 2018. Впервые Rust 2018 был упомянут в марте, затем в июле: прочтите их, чтобы понимать для чего нужен Rust 2018. Также, есть статья на сайте Mozilla Hacks.

Вкратце, Rust 2018 это возможность представить всю работу за последние три года в виде цельного пакета. Кроме возможностей языка, сюда входят:

  • Инструментарий (поддержка IDE, rustfmt, Clippy)
  • Документация
  • Работа различных рабочих групп
  • Новый веб-сайт

Для обозначения редакций Rust был представлен ключ edition в Cargo.toml:

[package]
name = "foo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2018"

[dependencies]

Значение 2018 означает, что используется редакция Rust 2018; отсутствие ключа или значение 2015 означает использование редакции Rust 2015.

Важно отметить, что каждый пакет может быть в редакциях 2015 или 2018, и они без проблем могут работать вместе. Проект под редакцией 2018 может использовать зависимости 2015, а проект 2015 использовать зависимости 2018. Это гарантирует целостность экосистемы, сохраняя совместимость существующего кода. Кроме того, существует возможность автоматической миграции кода с редакции Rust 2015 на Rust 2018 при помощи cargo fix.

Non-lexical lifetimes (NLL; Нелексические времена жизни)

В 2018 появились нелексические времена жизни, что на простом языке означает, что проверщик заимствований (borrow checker) стал умнее и теперь не отклоняет правильный код. Например:

fn main() {
    let mut x = 5;

    let y = &x;

    let z = &mut x;
}

В старых версиях этот код выдаст ошибку компиляции:

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

из-за того, что время жизни действует внутри лексического блока; то есть, заимствование будет удерживаться за y, пока y не покинет пределы main, несмотря на то, что y больше не используется. Сегодня этот код скомпилируется правильно.

Другой пример:

fn main() {
    let mut x = 5;
    let y = &x;
    let z = &mut x;
    
    println!("y: {}", y);
}

Старый Rust выдаст следующую ошибку:

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

В Rust 2018 вывод ошибки стал лучше:

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

Теперь, вместо того, чтобы показывать место, где y покидает пределы лексического блока, показывается место, где происходят конфликтующие заимствования. Это значительно облегчает отладку подобных ошибок.

Пока эти возможности доступны в Rust 2018, но в будущем планируется портировать их на Rust 2015.

Изменения в системе модулей

Редакция Rust 2018 привносит некоторые изменения в работу с путями, что в конечном итоге привело к упрощению системы модулей.

Вкратце:

  • extern crate больше не требуется практически во всех случаях.
  • Макросы теперь можно импортировать при помощи use вместо атрибута #[macro_use].
  • Абсолютные пути начинаются с названия пакета, где ключевое слово crate ссылается на текущий пакет.
  • foo.rs и поддиректория foo/ могут сосуществовать вместе; mod.rs больше не нужен при размещении подмодулей в поддиректории.

Полную информацию можно прочесть в руководстве.

Упрощенные правила синтаксиса времени жизни

В обеих редакциях представлены новые правила синтаксиса времени жизни для блоков impl и определениях функций. Следующий код:

impl<'a> Reader for BufReader<'a> {
    // methods go here
}
теперь может быть написан таким образом:
impl Reader for BufReader<'_> {
    // methods go here
}

'_ подсказывает, что BufReader берёт параметр, но больше нет необходимости именовать его.

В структурах времена жизни всё ещё должны быть определены, но теперь без лишнего кода:

// Rust 2015
struct Ref<'a, T: 'a> {
    field: &'a T
}

// Rust 2018
struct Ref<'a, T> {
    field: &'a T
}
: 'a добавляется автоматически. При желании, можно продолжать использовать явное определение.

const fn

Существует несколько способов определения функций в Rust: регулярная функция с fn, небезопасная функция с unsafe fn, внешняя функция с extern fn. В этом релизе появился ещё один способ: const fn, который выглядит следующим образом:

const fn foo(x: i32) -> i32 {
    x + 1
}
Функции const fn могут вызываться как регулярные функции, но вычисляются во время компиляции, а не во время выполнения. Для стабильной работы, они должны иметь детерминированный результат и в настоящее время ограничены следующим минимальным набором операций:

  • Арифметические операторы и операторы сравнения с целыми числами
  • Все логические операторы, кроме && и ||
  • Построение массивов, структур, перечислений и кортежей
  • Вызов других функций const fn
  • Задание индекса массивам и срезам
  • Доступ к полям структур и кортежей
  • Чтение из констант
  • & и * на ссылках
  • Приведение типов, за исключением необработанных указателей на целые числа

В будущем данный набор будет расширяться, подробную информацию можно посмотреть здесь.

Новые инструменты

Наряду с Cargo, Rustdoc, и Rustup, которые являются ключевыми инструментами с версии 1.0, редакция 2018 представляет новое поколение инструментов: Clippy, Rustfmt, и поддержку IDE.

Clippy является статическим анализатором кода в Rust, достиг версии 1.0 и теперь доступен в стабильной версии Rust. Установку можно произвести следующим образом: rustup component add clippy, запуск: cargo clippy.

Rustfmt является инструментом для автоматического форматирования кода Rust в соответствии с официальной стилистикой Rust. В этом релизе он достиг версии 1.0 и, начиная с этой версии, гарантируется обратная совместимость для Rustfmt: отформатированный сегодня код останется неизменным в будущем (только с опциями использованными по-умолчанию), и несёт практическую ценность при использовании с системами непрерывной интеграции (CI; cargo fmt --check). Установить Rustfmt можно следующим образом: rustup component add rustfmt, использовать: cargo fmt.

Поддержка IDE - одна из наиболее востребованных возможностей в Rust. Работы над поддержкой IDE ещё не закончены, но на данный момент уже существуют несколько высококачественных опций:

Tool lints

В Rust 1.30 были стабилизированы атрибуты инструментов, такие как #[rustfmt::skip]. В Rust 1.31 стабилизированы «анализаторы инструментов» («tool lints») наподобие #[allow(clippy::bool_comparison)], у них появилось своё пространство имён и теперь ясно к какому инструменту они относятся. Старые проверки Clippy теперь можно писать следующим образом, вам больше не нужен атрибут cfg_attr:

// old
#![cfg_attr(clippy, bool_comparison)]

// new
#![allow(clippy::bool_comparison)]

Документация

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

Рабочие группы

В этом году было объявлено о создании четырёх рабочих групп в следующих областях:

  • Сетевые сервисы
  • Приложения командной строки
  • WebAssembly
  • Встраиваемые устройства

Каждая из этих групп очень много работала над тем, чтобы сделать Rust лучше в своей области. Некоторые основные моменты:

  • Группа сетевых сервисов работает над интерфейсом Futures и async/await, который уже будет доступен в скором времени.
  • Группа командной строки работает над библиотеками и документацией для создания ещё лучших приложений для командной строки.
  • Группа WebAssembly выпустила огромное количество инструментария для использования Rust с wasm.
  • Группа встраиваемых устройств добилась поддержки разработки ARM на стабильной версии Rust.

Новый сайт

Основной сайт получил новый дизайн.

Стабилизация библиотек

Добавлено множество реализаций From:

  • u8 теперь реализует From<NonZeroU8>, то же самое для других числовых типов и их NonZero-эквивалентов
  • Option<&T> реализует From<&Option<T>>, аналогично для &mut

Были стабилизированы следующие функции:

  • slice::align_to и её изменяемый аналог
  • slice::chunks_exact и её изменяемый и r аналоги (такие как slice::rchunks_exact_mut) во всех комбинациях

Подробный список изменений можно посмотреть здесь.

Cargo

Cargo теперь загружает пакеты параллельно, используя HTTP/2. В связи с тем, что extern crate практически больше не требуется, было бы неудобно использовать пакет через extern crate foo as bar; Это можно сделать в Cargo.toml следующим образом:

[dependencies]
baz = { version = "0.1", package = "foo" }

или

[dependencies.baz]
version = "0.1"
package = "foo"

В примере выше, пакет foo теперь может быть использован через baz.

Подробный список изменений можно посмотреть здесь.

>>> Подробности

★★★★★

Проверено: Shaman007 ()
Ответ на: комментарий от meatich

и как в нем переживаются архитектурные изменения в больших проектах?

Для начала интересно было бы увидеть список больших проектов. А потом подсписок тех из них, у которых время эволюции больше хотя бы двух лет.

eao197 ★★★★★ ()
Ответ на: комментарий от meatich

как rust для быстрого прототипирования нынче?

Если вы его уже отлично знаете вместе с популярными библиотеками, то годится. Иначе в «быстро» не получится, тут не простенький Go, а скорее C++.

snizovtsev ★★★ ()
Ответ на: комментарий от meatich

как rust для быстрого прототипирования нынче?

прототипирования чего? Если не для околосистемщины, а для приклада типа промоделировать/посчитать-получить_результат-выкинуть, то необходимость возиться с временем жизни переменных будет только тормозить разработку.

В этом смысле даже С++ проще, и кстати, когда Страуструп решил его запилить, ему это ЕМНИП нужно было для исследований в области распределенных систем.

seiken ★★★★ ()
Ответ на: комментарий от meatich

как rust для быстрого прототипирования нынче?

Как для быстрого прототипирования язык, который известен своим строгим компилятором, а также «страшным» синтаксисом, заточенными под безопасную системщину? Ну, примерно никак.

и как в нем переживаются архитектурные изменения в больших проектах?

Хорошо должны переживаться. Rust неплохо спроектирован, да и ООП там нет.

Crocodoom ★★ ()
Ответ на: комментарий от seiken

прототипирования чего?

Ну да, для того, для чего создавался - для околосистемщины.

В этом смысле даже С++ проще

А если предположить, что как заметил товарищ сверху,

вы его уже отлично знаете вместе с популярными библиотеками

?

Наверняка ведь в этом случае что раст что плюсы одинаково выходят по времени в мелких проектах (мелкий - скажем, в неделю кодинга).

Это уже немного другое, но когда последний раз интересовался, раст смотрелся очень живо для работы с опенжеле. Был там один грамотный враппер, способствующий этому, исключал выстрел в ногу на этапе компиляции во многих случаях. Ну, это конечно на фоне того, что OpenGL на С++ запомнился не иначе как кошмар, где нужно быть внимательнее дрища в Мытищах и где булки на расслабить ни на единую секунду. Это ощущение должно быть проходит с опытом, но забыть его полностью не представляется возможным.

meatich ()
Ответ на: комментарий от Crocodoom

Хорошо должны переживаться. Rust неплохо спроектирован, да и ООП там нет.

А для полноты картины, у кого нибудь есть охренительные истории про архитектурные изменения в проектах на плюсах и их последствия? Так, для подливания масла в огонь того что бы знать с чем имеем дело, найти юзкейс так сказать, и подумать как бы это решилось на расте.

meatich ()
Ответ на: комментарий от meatich

охренительные истории про архитектурные изменения в проектах на плюсах и их последствия

Кастую всех ООП-хейтеров. Они вам много интересного расскажут.

PS: подливая масла в огонь, я был в шоке когда узнал, что std::variant по умолчанию содержит тот тип, у которого есть конструктор по умолчанию. То есть убрав конструктор у типа можно получить забавные проблемы.

RazrFalcon ★★★★★ ()

Новый сайт
Основной сайт получил новый дизайн.

Вот тут у меня щёлкнуло, почему вокруг раста столько хайпа: похоже, «талантливых маркетологов» вокруг раста собралось заметно больше, чем инженеров и учёных.

anonymous ()
Ответ на: комментарий от Crocodoom

Как для быстрого прототипирования язык, который известен своим строгим компилятором

Быстрое прототипорование это сколько строк? По моим ощущениям, когда «прототип» переваливает за 200 строк и 3 файла, мозг человеческий начинает невообразно делать ошибки и вся надежда только на строгий компилятор

spoonbob ()
Ответ на: комментарий от tailgunner

Надо дивно упороться, чтобы утверждать про опережение по ясности. Кресты тоже как бы не чемпион по ней, но ржавый находится глубоко внизу, в одной придонной лиге вместе с перлом.

Joe_Bishop ()
Последнее исправление: Joe_Bishop (всего исправлений: 1)
Ответ на: комментарий от snizovtsev

как rust для быстрого прототипирования нынче?

Если вы его уже отлично знаете вместе с популярными библиотеками, то годится.

Да не сказал бы. Мучительно больно не будет, но если вы отлично знаете питон вместе с популярными библиотеками, то будет сильно побыстрее.

mersinvald ★★★★ ()
Ответ на: комментарий от TatriX

Ох они это такую дичь придумали, совсем не по растовски. В Actix надо типо чтобы была запущена система. Что это значит вообще? Как он не видит? У меня от этой магии бомбит. И да, потом паники. У меня в Токио была паника только в прод билде, внутри фреймворка, но не в дебаге чтобы я мог отдебажить. Сволочи

vertexua ★★☆☆☆ ()
Последнее исправление: vertexua (всего исправлений: 1)