LINUX.ORG.RU

Rust 1.17

 ,


3

9

Команда Rust рада представить выпуск Rust 1.17.0. Rust — это системный язык программирования, нацеленный на безопасность, скорость и параллельное выполнение кода.

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

$ rustup update stable

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

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

Выпуск Rust 1.17.0 в основном вносит небольшие улучшения, преимущественно касающиеся удобства использования. Например, время жизни 'static теперь автоматически подразумевается для констант или статических переменных. При создании константы или статической переменной:

const NAME: &'static str = "Ferris";
static NAME: &'static str = "Ferris";

Rust 1.17 позволит вам больше не писать 'static, так как это единственное время жизни, которое имеет смысл:

const NAME: &str = "Ferris";
static NAME: &str = "Ferris";

В некоторых ситуациях это позволит избавиться от лишних повторений:

// было
const NAMES: &'static [&'static str; 2] = &["Ferris", "Bors"];

// стало
const NAMES: &[&str; 2] = &["Ferris", "Bors"];

Другим подобным косметическим улучшением является «короткая инициализация полей». Подобно ECMAScript 6, который называет это «Сокращение Значения Свойства Объектного Литерала» («Object Literal Property Value Shorthand»), дублирование может быть удалено при объявлении структур, к примеру:

// определение
struct Point {
    x: i32,
    y: i32,
}

let x = 5;
let y = 6;

// было
let p = Point {
    x: x,
    y: y,
};

// стало
let p = Point {
    x,
    y,
};

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

Другое маленькое, но полезное улучшение касается в основном новичков в Rust, которые пытаются использовать +, чтобы соединить две &str вместе. Но это не работает, соединить вы можете лишь String + &str. Поэтому, было добавлено новое сообщение об ошибке, чтобы помочь пользователям, которые совершают подобную ошибку:

// код
"foo" + "bar"

// было
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^
  |
note: an implementation of `std::ops::Add` might be missing for `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^

// стало
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
 --> <anon>:2:5
  |
2 |     "foo" + "bar"
  |     ^^^^^
  |
  = note: `+` can't be used to concatenate two `&str` strings
help: to_owned() can be used to create an owned `String` from a string
reference. String concatenation appends the string on the right to the string on
the left and may require reallocation. This requires ownership of the string on
the left.
  |     "foo".to_owned() + "bar"

При использовании сценариев сборки Cargo вы должны указать расположение скрипта в вашем Cargo.toml. Однако, подавляющее большинство людей писали build = «build.rs», тем самым используя файл build.rs, расположенный в корне проекта. Теперь это соглашение поддерживается самим Cargo, и будет использовано по умолчанию, если существует файл build.rs. Мы предупреждали об этом изменении в течение нескольких последних выпусков. Вы также можете использовать build = false для отказа от этого соглашения.

В этом выпуске удалена старая система сборки на основе Makefile. Новая система, анонсированная в Rust 1.15, написана на Rust и в основном использует Cargo для управления сборкой. На данный момент она уже достаточно зрелая, чтобы быть единственной системой сборки.

В рамках этого изменения, пакеты из crates.io теперь можно использовать в системе сборки Rust. Первым был добавлен mdBook, и он теперь используется при сборки нашей разнообразной книжной документации:

Обратите внимание на ссылки на соответствующие репозитории; документы были перемещены из основного дерева. Кроме того, мы добавили четвертую книгу, которая все еще расположена в основном дереве: Книга «Нестабильные возможности Rust». Она описывает нестабильные возможности, содержит ссылки на задачи, связанные с их стабилизацией, и может содержать исходную документацию. Если есть возможность, которую вы хотите увидеть стабилизированной, то пожалуйста, примите участие в ее обсуждении!

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

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

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

Был стабилизирован 21 новый интерфейс:

  • Arc::into_raw и Rc::into_raw позволят вам забрать Arc или Rc и получить сырой указатель.
  • Arc::from_raw и Rc::from_raw позволят вам забрать сырой указатель и получить Arc или Rc.
  • Arc::ptr_eq и Rc::ptr_eq возвращает true если оба Arc или оба Rc указывают на одно и то же значение (не обязательно значения, которые сравниваются, равны).
  • Ordering::then позволит вам сцепить два Ordering вместе, и Ordering::then_with позволит сделать это с помощью функции.
  • BTreeMap::range позволит вам итерировать лишь по части BTreeMap, и BTreeMap::range_mut позволит вам сделать это с возможностью изменения. collections::Bound может дать вам еще больше контроля.
  • process::abort будет полностью завершать процесс анормальным образом.
  • ptr::read_unaligned и ptr::write_unaligned аналогичны ptr::read и ptr::write, но без требований к выравниванию.
  • Result::expect_err зеркально подобен Result::expect, то есть работает с вариантом Err, а не с вариантом Ok.
  • Cell::swap аналогичен std::mem::swap, но позволяет вам делать это с &Cell вместо &mut T.
  • Cell::replace аналогичен std::mem::replace, но позволяет вам делать это с &Cell вместо &mut T.
  • Cell::into_inner позволит вам взять Cell, и извлечь его значение.
  • Cell::take позволит вам забрать значение Cell наружу, заменив его на Default::default.

Что касается других изменений, для многих методов Cell<T> требовалось ограничение T: Copy, но теперь это требование значительно ослаблено.

Box<T> теперь реализует более дюжины новых преобразований с помощью From.

SocketAddr и IpAddr также теперь имеют несколько новых преобразований. Раньше вы должны были писать код вроде этого:

"127.0.0.1:3000".parse().unwrap()

Сейчас же вы можете писать
SocketAddr::from(([127, 0, 0, 1], 3000))
// или
([127, 0, 0, 1], 3000).into())

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

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

Возможности Cargo

Помимо ранее упомянутых изменений, касающихся build.rs, у Cargo есть еще несколько новых улучшений. cargo check --all и cargo run --package — два отсутствовавших до этого момента флага, которые теперь поддерживаются.

Теперь вы можете игнорировать проверки отзыва SSL. Конечно, по умолчанию проверка все еще производится.

Новое поле в Cargo.toml, required-features, позволяет указать конкретные возможности, которые должны быть установлены для цели, которую нужно собрать. Вот пример: предположим, что мы пишем контейнер, который взаимодействует с базами данных, и хотим, чтобы он поддерживал несколько баз данных. Мы могли бы это сделать в нашем Cargo.toml:

[features]
# ...
postgres = []
sqlite = []
tools = []

Возможность tools позволяет нам включить дополнительные инструменты, а возможности postgres и sqlite указывают, какие базы данных мы хотим поддерживать.

Раньше cargo build пыталась собрать все цели, которые вам нужны. Но что, если у нас есть файл src/bin/postgres-tool.rs, который является нужным только при условии, что возможности postgres и tools были включены? Раньше нам приходилось писать что-то вроде этого:

#[cfg(not(all(feature = "postgres", feature = "tools")))]
fn main() {
    println!("This tool requires the `postgres` and `tools` features to be enabled.");
}

#[cfg(all(feature = "postgres", feature = "tools"))]
fn main() {
    // код
}

Слишком много шаблонного кода для работы с cargo build. Еще печальнее дело обстояло с examples/, которые должны демонстрировать, как использовать вашу библиотеку. Но такие махинации возможны только при работе внутри самого пакета, поэтому вы потерпите неудачу, если попытаетесь использовать пример вне этого пакета.

С помощью нового ключа required-features мы можем добавить следующее:

[[bin]]
# ...
required-features = ["postgres", "tools"]

Теперь cargo build будет собирать наш postgres-tool, только если у нас включены две эти возможности, и поэтому мы можем написать нормальный fn main без всяких нагромождений вроде cfg.

Разработчики версии 1.17.0

Много людей внесли свой вклад в создание Rust 1.17. Мы не смогли бы сделать это без всех вас. Спасибо!

Авторы перевода и публикации @kgv, @vitvakatu, @ozkriff.

>>> Подробнее смотрите примечания к выпуску

★★★★★

Проверено: Shaman007 ()
Последнее исправление: sudopacman (всего исправлений: 3)
Ответ на: комментарий от mersinvald

При чем тут гоферы? Ты просто делишь мир на белое и черное, серебрянные пули и коровьи лепешки, причина явно не в моей неправоте.

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

Это те ошибки, которые действительно зависят от квалификации программиста, а не от инструмента..
Как анализ поможет отличить нужный кэш от ненужного кэша? Рантайм-анализ возможно на определенном этапе и сможет давать такие диагностики, но растовские проверки статитические.

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

Ну а разве есть еще языки, в которых неиспользуемая переменная — ошибка? (как будто это хоть как-то спасает от логических утечек, лол)

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

Понятия не имею, разве что какой нибудь чистый функциональный язык, где есть только выражения и все есть функция. Единственное что я пытался сказать — раст гарантирует отсутствие висячих указателей и прочего, а не утечек памяти.

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

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

Окей, но зачем? Это же и говорит официальная документация Rust. Ни от обычных ни от логических утечек ownership/borrowing не защищает. Ответственность за первое лежит на плечах авторов инфаструктурного unsafe-кода, а за второе — на всех остальных.

По крайней мере первый тип утечек жестко локализован в unsafe, а второй контролируем без вмешательства в возню с указателями и памятью непосредственно.

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

Оно всегда требует литерала в качестве формата

println!() работает, но да, подсунуть так левую строку не получится.

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

Это не вставки, а файл, написанный целиком. Ты плохо искал.

Кстати, а че не привел сразу код mbr?

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

Двачую этого благородного дона.

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

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

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

С учетом того, до какой степени Mozilla кастрировала C++ в своих гайдлайнах

Неужели сильнее чем гугл? Самому искать лень, так что поверю на слово.

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

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

Люди склонны ошибаться, тут ничего не поделаешь. Так что если какой-то инструмент ценой приемлемых ограничений может обеспечить отсутствие (пусть и строго определённого вида) ошибок, то разве это плохо? Дальше всё упирается как в то считаем ли мы ограничения приемлемыми, «консервативность»/легаси, ну и «здравый смысл» (бросаться каждый раз переписывать всё подряд нет смысла).

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

https://developer.mozilla.org/en-US/docs/Mozilla/C _Portability_Guide Запретили статические конструкторы, RTTI, initializer lists, исключения и STL. Еще требуют либо explicit у конструктора, либо руками удалить операторы присвоения и копирования.

Хз чего такого прям «кастрированного» в этом C++, вполне разумные требования — лямбды есть, все есть, кроме конкретного мусора вроде STL и исключений с RTTI которые итак никто не использует.

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

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

О_О Долго над примером думал?

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

Это скорее в c++/rust не правильно ведь возможны утечки памяти. В языках с нормальным GC утечек не будет. Добавь сюда ошибки связанные с переполнением и нулевые указатели и поймёшь что плюсы это не только способ прострелить себе ногу, но и возможность не замечать этого.

более того, раст привлекает бракоделов, у которых бомбит от С++ потому что в С++ их говнокод падает.

Перила у себя в доме спилил?

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

Ну придумай название получше для момента когда программа грохнется с OutOfMemory.

Если я запрошу 5 ТБ оперативки на твоём десктопе, то это тоже утечка будет? А ведь я каждый байт там буду использовать!

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

В языках с нормальным GC утечек не будет.

А если я забыл написать static перед class и захватил this родителя, хотя и не хотел этого делать, это что не будет утечкой?

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

И где тут будет утечка? Выглядит как ситуация, которую любой современный GC сможет разрулить (цикличиская ссылка). Или я что-то не понял?

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

И где тут будет утечка?

как это где, прямо тут и будет утечка. Родитель останется жить все время пока живет дочерний обьект. И gc не сможет его удалить. Такое часто встречается на андроиде, когда случайно захватывают Activity и оно висит в памяти мертвым грузом.

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

А если я забыл написать static перед class и захватил this родителя, хотя и не хотел этого делать, это что не будет утечкой?

У тебя есть класс A который должен быть статическим, но при этом в нём используется this? Что то ерунда получается.

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

В Java есть внутренние классы. Они могут быть статическими, тогда они работают как обычные классы, либо не статическими, тогда экземпляры создаются с помощью особого синтаксиса (outer.new InnerClass(), тк нужно передать в конструктор ссылку на экземпляр внешнего класса, но внутри методов где this внешнего класса доступен this.new можно заменить просто на new) и такие классы хранят this внешнего класса. Правда непонятно откуда тут возьмется утечка, обычная циклическая ссылка по описанию и сборщик мусора должен быть ну очень наивным, чтобы такое не собрать. Не сталкивался с андроидом, мб там действительно такой ущербный GC.

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

Ты как будто вообще не видел Java и не знаешь что такое static. Ну ладно, вот пример:

public class Heavy {
    private int[] data = new int[100000000];

    public Result compute() {
        long sum = 0;
        for (int i = 0; i < data.length; i++) {
            sum += data[i];
        }
        return new Result(sum);
    }

    public class Result {
        public long result;

        public Result(long r) {
            this.result = r;
        }
    }
}
pftBest ★★★★
()
Ответ на: комментарий от anonymous

Не сталкивался с андроидом, мб там действительно такой ущербный GC.

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

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

Ты как будто вообще не видел Java и не знаешь что такое static.

Я видел java не на столько хорошо чтоб о ней судить. Я видел C#.

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

и такие классы хранят this внешнего класса.

и сборщик мусора должен быть ну очень наивным, чтобы такое не собрать.

А зачем собирать, если есть ссылка? Вдруг она через пару секунд понадобится?

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

В C# наверное нет такого, потому что nested class не захватывает ссылку на родителя. Так что прострелить себе ногу сложнее.

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

Нет, никакой магии, просто это удобно. Иногда не хочется создавать отдельный файл под Result. А еще когда их много, то удобно держать каждый Result рядом с его Heavy, тогда сразу видно какой Result откуда взялся.

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

Иногда не хочется создавать отдельный файл под Result.

Кажется я начинаю вспоминать. java не терпит когда в файле более одного класса? Это черезвычайно не удобно же.

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

Согласен, Java хреновый язык. Если мне нужно сделать что либо для jvm или android, я беру Kotlin и не мучаюсь.

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

java не терпит когда в файле более одного класса?

Терпит сколько угодно, но только один из них должен быть public и называться так жк как и файл

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

В данном случае не обязательно.
Но, например как внутреннюю реализацию какого-нибудь интерфейса.
Без возможности создать экземпляр этого класса снаружи( private class ).
Что зачастую очень удобно.

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

Пока не будет компилятора «C» для сравнения все это будет: бла-бла-бла

Серьёзно? Надо бросаться писать на расте компилятор С просто чтобы ты что-то там засчитал придумал новые критерии почему это ничего не значит?

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

ОС пишут но скорее для фана и экспериментов, чем как когда-то на Си, который был создан специально чтобы переписать UNIX с ассемблера.

Язык многие компании внедряют для разработки инфаструктурных продуктов, некоторые стартапы используют как основной. Ниша раста еще не сформирована, короче, всё происходит прямо сейчас и прогнозы делать трудно)

mersinvald ★★★★★
() автор топика
Последнее исправление: mersinvald (всего исправлений: 1)
Ответ на: комментарий от shkolnick-kun

Рабочие репозитории с обсуждениями тут: https://github.com/ruRust
Идейный вдохновитель — mkpankov, связаться можно через тот же чат в гиттере.

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

Серьёзно? Надо бросаться писать на расте компилятор С просто чтобы ты что-то там засчитал придумал новые критерии почему это ничего не значит?

Пук-пук-пук. Из достижений rust'а есть только rustcc и cargo, эффективность которых... Да не с чем сравнивать, за 7 лет так и не выкатилось ни одного продукта на rust'е. Отсюда вывод - не стоит никому связываться с этой хипстотой, не нужно терять свои силы и время. rust == ненужно.

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

Семь лет? ты считать умеешь? на днях 2 года исполнилось. Для сравнения Go 1.0 вышел в 2009, вот ему как раз семь лет.

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

Вчера смотрел на ютубе. Некие «котаны» из украины переписали на расте c++/activex компоненту браузерного шифрования для банков. Затем скомпили этот раст в wasm и получили нативное кроссбраузерное шифрование, совместимое с существующей банковской инраструктурой

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

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

Давай только уточним ставишь ли ты джаву и C# в один ряд или нет.

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

Это так сложно сделать?

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

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

ух, насношался я с вашим растом. вот, лови, проверь работает или нет. если все збс - в ближайшие пару дней накатаю скриптец как это все обновлять без лишней боли и залью куда-нибудь, скажем на гитхаб. тогда самым диким будет собственно поставить obs-клиент и завести там аккаунт.

в целом можно написать скрипт к тревису чтоб он автоматом при удачном билде делал вендоринг и закидывал все в obs, но если честно - я бы лучше руками обновлял при стабильном релизе. потому и предлагаю скрипт написать.

ну и вендоринг конечно некошерно с точки зрения всяких растов, но пока нет нормальной структуры пакетов и правил их оформления в различных дистрах - лучше так.

а, ну и мне было лень менять некоторые поля, скажем копирайт в deb, переделаю как время будет. я ж тоже не с нуля набивал прям все подряд.

если сделаешь акк - могу поставить мейнтейнером, ну или просто скопируешь все и тогда удалю свой реп. кстати остальных растолюбов это тоже касается - в целом компилятор упаковал под все дистры, проблемы могут быть только со старым gcc или cmake для отдельных либ.

p.s. компилятор из статики, каюсь. но хотя бы упакованный

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

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

... (скорее всего) будет варнинг. Хотя, конечно, можно проигнорировать или написать код так, что предупреждения не будет.

DarkEld3r ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.