LINUX.ORG.RU

Вышел Rust 1.20

 


2

7

Команда разработчиков Rust с удовольствием объявляет о выходе новой стабильной версии Rust: 1.20.0.

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

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

rustup update stable

(Прим. пер. - иногда предварительно нужно выполнить rustup self update)

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

Что нового в стабильной версии Rust 1.20.0

В предыдущих версиях Rust вы уже могли определять «ассоциированные функции» для трейтов, структур и типов-сумм:

struct Struct;

impl Struct {
    fn foo() {
        println!("foo - это ассоциированная функция структуры Struct");
    }
}

fn main() {
    Struct::foo();
}

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

В Rust 1.20 добавлена возможность использовать «ассоциированные константы»:

struct Struct;

impl Struct {
    const ID: u32 = 0;
}

fn main() {
    println!("ID структуры Struct: {}", Struct::ID);
}
Здесь константа ID ассоциирована со структурой Struct. Как и функции, ассоциированные константы могут быть определены для трейтов и типов-сумм.

Использование ассоциированных констант в трейтах предоставляет дополнительные возможности. Ассоциированная константа в трейте используется также, как и ассоциированный тип: её можно определить, не присваивая ей значение. Значение константы будет указано при реализации трейта:

trait Trait {
    const ID: u32;
}

struct Struct;

impl Trait for Struct {
    const ID: u32 = 5;
}

fn main() {
    println!("{}", Struct::ID);
}
В предыдущих релизах Rust при реализации трейта, представляющего числа с плавающей точкой, приходилось писать такой код:
trait Float {
    fn nan() -> Self;
    fn infinity() -> Self;
    ...
}
Это немного неудобно, но, что более важно, такие функции невозможно использовать для определения констант. Из-за этого приходилось вводить дополнительные константы:
mod f32 {
    const NAN: f32 = 0.0f32 / 0.0f32;
    const INFINITY: f32 = 1.0f32 / 0.0f32;

    impl Float for f32 {
        fn nan() -> Self {
            f32::NAN
        }
        fn infinity() -> Self {
            f32::INFINITY
        }
    }
}
Ассоциированные константы позволяют реализовать всё это намного проще. Трейт будет выглядеть таким образом:
trait Float {
    const NAN: Self;
    const INFINITY: Self;
    ...
}
А его реализация станет намного проще и расшит возможности использования трейта:
mod f32 {
    impl Float for f32 {
        const NAN: f32 = 0.0f32 / 0.0f32;
        const INFINITY: f32 = 1.0f32 / 0.0f32;
    }
}
Ассоциированные константы были предложены три года назад в RFC 195. И мы наконец смогли их реализовать! Этот RFC содержал все виды ассоциированных элементов, не только константы. Некоторые из них мы смогли реализовать быстрее чем другие. Мы много работаем над улучшением поддержки работы с константными выражениями, чтобы увеличить возможности Rust в области мета-программирования во время компиляции. В будущем в этой области появятся дополнительные возможности.

Кроме того, мы исправили ошибку при работе с макросом include! в тестах документации: пути к файлам определялись относительно рабочего каталога, а не каталога, в котором находится файл кода.

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

В этом релизе не произошло значительных изменений в стандартных библиотеках. Внесено несколько полезных улучшений и продолжается работа по стабилизации API.

Макро unimplemented! теперь принимает параметр, в котором можно указать причину отсутствия реализации.

Добавлена поддержка Unicode 10.0.0.

Функции min и max были переписаны на Rust, и больше не используют cmath.

Внедрена защита от уязвимости Stack Clash. Основные изменения: stack probes и отключение дополнительных ручных проверок для стека основного потока. Для включения защиты достаточно скомпилировать проект в Rust 1.20, изменения в коде не требуются.

В стандартную библиотеку добавлены три новые функции сортировки: slice::sort_unstable_by_key, slice::sort_unstable_by и slice::sort_unstable. Как вы заметили, все три содержат «unstable» в названиях. Стабильность — это свойство алгоритма сортировки, которое требуется не всегда, но раньше в стандартной библиотеке не было алгоритмов нестабильной сортировки. Теперь доступны обе возможности! Для демонстрации разницы между этими видами сортировки рассмотрим список:

rust
crate
package
cargo
Список, отсортированный алгоритмом стабильной сортировки только по первой букве, должен выглядеть таким образом:
crate
cargo
package
rust
То есть, если в исходном списке слово crate предшествовало слову cargo, то и в отсортированном списке оно должно стоять первым. Алгоритм нестабильной сортировки тоже может выдать такой результат, но допускается и вариант с измененной последовательностью:
cargo
crate
package
rust
Как вы понимаете, меньшее количество ограничений часто позволяет создать более быстрый алгоритм. Если вам не важна стабильность сортировки, нестабильная сортировка может оказаться быстрее, чем стабильный вариант. Как обычно, лучше попробовать оба варианта и сравнить их скорость. Эти функции сортировки были добавлены в RFC 1884. По ссылке вы можете узнать больше подробностей, включая результаты бенчмарков.

Также были стабилизированы следующие API:

и некоторые другие.

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

Этот релиз внес полезные улучшения в менеджер пакетов cargo. Первое и самое важное: токен аутентификации для crates.io хранился в ~/.cargo/config. Обычно маска доступа для файлов конфигурации устанавливается в 644, то есть чтение разрешено всем. Но в этом файле хранится секретный токен. Мы переместили токен в отдельный файл ~/.cargo/credentials, таким образом для него может быть установлен доступ 600, и он будет скрыт от других пользователей системы.

Если вы использовали пакеты Cargo, создающие дополнительные исполняемые файлы, вы знаете, что их исходный код хранится в src/bin. Но иногда вам может понадобиться создать несколько дополнительных исполняемых файлов, требующих много кода. В этом случае код может храниться в файлах src/bin/client.rs и src/bin/server.rs и все субмодули этих файлов попадут в один каталог, что неудобно и создает путаницу. Теперь мы используем соглашение, что такие файлы как src/bin/server/main.rs и src/bin/client/main.rs также используются для создания дополнительных исполняемых файлов. Это позволяет удобнее разграничить код.

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

★★★

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

Вот именно если я считаю какое-то математическое выражение я ожидаю получить правильный ответ или хоть какую-то индикацию что произошла ошибка. А разработчики Pony предлагают молча получить неправильный ответ. Разве это безопасно?

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

знать плюсы можно и без опыта коммерческой разработки

Да ты прям ниндзя. И чо, все сообщество у ржавых такое пионэрское? Ну и цирк.

bread
()
Ответ на: комментарий от shkolnick-kun

Я сорцы не смотрел, но у heartbleed был баг из-за выхода за пределы массива. rust просто упадёт с паникой. Данные украсть не выйдет.

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

вот есть куча софта написанного на крестах и си. Как в них борются с фрагментацией?

Проблема фрагментации преувеличена. В 99.9% случаев такой проблемы не возникает. malloc-и не дураки пишут и там принято множество мер против фрагментации.

Или просматривая особым образом сформированные папки можно уронить файловый менеджер?

Нельзя.

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

К слову в rust вообще jemalloc, который борется с этой «проблемой».

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

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

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

Спорно, стабильные сортировки как правило менее эффективны в среднем чем нестабильные

Это из разряда считать последние такты. Ну или сортировать миллионы. Если уж этим занимаешься, подумать о том, какая сортировка оптимальней для твоего случая несложно. А асимптотика там одинаковая. Сильно проиграть в любом случае не получится.

а обычному пользователю на это пофиг

Ну вот утверждается что не пофиг. Что программисты не ожидают, что sort может менять местами отсортированные элементы и это вызывает трудно находимые баги. В тестах сортировка работала как положено (случайно), а в продакшне баг.

если не пофиг могли бы ввести стабильный аналог а-ля stable_sort

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

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

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

gene1
()

а в чем щас модно писать на расте? ну вот чтоб создал проект (ну или загрузил готовый карговский) и запустил одной кнопкой и бкякпоинты там, отладка...Ну чтоб совсем просто, а не emacs

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

Вообще-то filter/map/take это классические техники ФП, а в императивных ЯП их обычно и реализуют с помощью итераторов.

в императивных ЯП их обычно и реализуют с помощью итераторов

Но ассоциирует эти функции с итераторами, по-моему, только Rust:

  • Python - functools
  • Java - Stream API
  • Kotlin - Collections API
  • C# - LINQ
  • PHP - array_* functions
  • C++ - range-v3
  • Ruby - Collections API
NegatiV
()
Ответ на: комментарий от NegatiV

Напишу, о чем знаю.

Python - functools

В питоне коллекции лежат в itertools (в том числе и ленивые версии map/filter/reduce) + генераторы с yield + генераторные выражения. Всё это — итераторы. Стрим, итератор — синонимы одного и того же. В функциональных ЯП ленивость искоропки, там и заморачиваться с ней не нужно.

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

VS Code / Sublime Text 3. Совсем просто.

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

Сложная это задача

Lazarus делает это легко.

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

Но ассоциирует эти функции с итераторами, по-моему, только Rust

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

bread
()
Ответ на: комментарий от quantum-troll

Да, там довольно бессмысленный unsafe.

Отличная отмазка. Зачем же вы им обмазываетесь тогда везде? Вообще не видел растокода без unsafe, ну кроме хеловорда разфлакона.

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

Почему не сделать такой же лазарус-раст?

Им ООП не завезли, не знал что ли? Без нормального наследования никакой гуйни не будет, а с этими задвигами за безопасность не будет даже подобия GTK.

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

Я просто не люблю с фанатиками общаться. Их не убедить ни в чем.

Почему бы не сделать ide как Lazarus для rust? При чем здесь паскаль вообще?

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

титаническая задача

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

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

Сколько времени прошло между первой версией С и кроссплатформенным гуи? А у С++?

Своя библиотека есть в RedoxOS, но в остальных случаях есть и биндинги к Qt и Gtk.

O02eg ★★★★★
()
Ответ на: комментарий от shkolnick-kun

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

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

Сколько времени прошло между первой версией С и кроссплатформенным гуи?

У вас вечно этот анахронизм лезет. Чтобы на Си гуи написать нужно было сначала его вообще придумать как концепцию и прокачать ПК. А то так и вижу Ричи, радостно лабающего гуи на текстовом терминале. Ранний C++ туда же. А вот когда осилили достаточно быстрое ООП на ПК и оформились паттерны, гуи-либы как грибы наросли. Лучше признайтесь, что мозилле гуи никакие не нужны, как и хипсторам впрочем. Вам родина браузер дала, вот и трахайтесь там с домом на скриптах.

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

Вы создали 3 одинаковых сообщения про лазарус, а фанатик я.

Почему бы не сделать ide как Lazarus для rust?

Так вам GUI фреймворк нужен или IDE? Если IDE - есть vscode и sublime. Если GUI либа - то её нет. И на написание уйдёт с десяток лет (на любом языке).

При чем здесь паскаль вообще?

Lazarus на паскале.

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

Расскажи, чем тебе не нравится Glade? Рисуешь в нем свои формочки, а потом загружаешь их одной строчкой:

extern crate gtk;
use gtk::prelude::*;
fn main() {
    if gtk::init().is_err() {
        println!("Failed to initialize GTK.");
        return;
    }
    let glade_src = include_str!("builder_basics.glade");
    let builder = gtk::Builder::new_from_string(glade_src);

    let window: gtk::Window = builder.get_object("window1").unwrap();
    let button: gtk::Button = builder.get_object("button1").unwrap();
    let dialog: gtk::MessageDialog = builder.get_object("messagedialog1").unwrap();

    button.connect_clicked(move |_| {
        dialog.run();
        gtk::main_quit();
    });

    window.show_all();
    gtk::main();
}
http://gtk-rs.org

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

на написание уйдёт с десяток лет (на любом языке)

Ну-ну, а вот некто Джон Оустерхаут сообщает: I began work on Tk in late 1988, but it was a part-time project, so it took about two years before there was enough functionality for Tk to be useful.

Не стыдно, ржавые?

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

А на сишке то будет даже поприятнее.

Нет, не будет.

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

А как еще назвать сущность, выполняющую некий код для каждого элемента коллекции?

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

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

Он перегружен только в русском языке, в англоязычной литературе под stream обычно понимают поток данных. Конкретно в Java Stream API - это инструмент обработки потоков данных.

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