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)
Ответ на: комментарий от bread

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.

Перевод: только через 2 года он стала пригодным к использованию. И только для платформы X11. При том, что конкурировал только с Athena и платным motif. До зрелого состояния активно дорабатывался ещё лет 6. С появлением Qt и GTK стал никому не интересен, кроме пишущих на Tcl.

Тому, кто лезет в эту нишу сейчас, нужно иметь поддержку виджетов GTK, Qt, WinAPI, андроида, и наверное Mac OS X с iOS тоже. Иначе не взлетит.

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

Да как вы уже надоели! Идеи раста не новы, были языки до него с таким подходом ,просто раст пиарится во всю

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

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

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

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

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

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

Мне кажется никто кроме джавы не называет это Stream.

InputStream, FileStream, iostream, stringstream, QDataStream, System.IO.BufferedStream, тысячи их... они все работают не с элементами произвольного типа, а конкретно с последовательностью байт.

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

А например тот же LINQ про который тут говорили весь построен на интерфейсе IEnumerable который и является классическим итератором.

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

Перевод: только через 2 года он стала пригодным к использованию. И только для платформы X11.

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

нужно иметь поддержку виджетов GTK, Qt, WinAPI, андроида, и наверное Mac OS X с iOS

Жесть. Где это такое видано? Нет, простых гуев для линукса и венды для начала хватило бы. Не надо никаких гтк, упаси тнб.

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

Мне кажется никто кроме джавы не называет это Stream.

Ага, я даже небольшой список привел с названием соответствующих модулей/API в других ЯП. Я просто выразил легкое удивление по поводу того что технику ФП так «пристегнули» к чисто императивному механизму итераторов, ведь по сути без разницы что там под капотом у filter/map/take/collect.

P.S. тоже согласен, что Stream не самое удачное название, но, имхо, расширение интерфейса Iterator<T> функциями filter/map/take/collect мне кажется еще более спорным (поправьте, если трейты Rust и интерфейсы Java как-то принципиально отличаются)

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

Нет, простых гуев для линукса и венды

Винда стала революцией (в сравнении с ДОСом) из-за гуя. Но их гуй до сих пор не кросплатформенный. Более того, их гуй так глубоко вплелся в систему, что и через 100 лет нейроинтерфейс Windows 20 будет не избавится от наследия WinAPI. В макоси похожая история. А ты говоришь «простой гуй». Простых гуёв не бывает. Либо сложные либо убожетсво

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

Нет, простых гуев для линукса

Лучший способ всех распугать.

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

расширение интерфейса Iterator<T> функциями filter/map/take/collect мне кажется еще более спорным

Так сделано не только в расте, но например в C#, Scala, Kotlin, Swift, и может быть еще во многих других языках которые я не знаю.

трейты Rust и интерфейсы Java как-то принципиально отличаются

трейты это интерфейсы из java 8. Точнее наоборот, в java 8 интерфейсы стали трейтами.

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

Так сделано не только в расте, но например в C#, Scala, Kotlin, Swift, и может быть еще во многих других языках которые я не знаю.

В Kotlin это сделано через extension functions над коллекциями (т.е. все конечно свелось к банальному for (... in this) {}, но интерфейс Iterator<T> они не расширяли). В Scala эти операции сделаны через implicit conversion к WrappedArray (как пример). Все-таки использовать итератор для реализации определенного поведения это не тоже самое что расширить интерфейс итераторов.

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

Я не вижу принципиальной разницы между default method и extension method для того же интерфейса. Запись разная а суть та же самая, и работает одинаково.

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

Такое решение хорошо тем, что в расте достаточно реализовать метод next(&mut self) -> Option<Item> чтобы получить всю машинерию функциональных примитивов.

В Java реализовать свой т.н. Stream — очень много геморроя.

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

Но есть разница между extension/default method для Iterator<T> и extension method для Collection<T>. Имхо, второй вариант значительно гибче.

NegatiV
()

Забыли добавить в Release Notes, что из Rust-а сбежал ТОП-1 по коммитам разработчик.

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

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

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

Автор в блоге у себя писал. Если не ошибаюсь, тупо надоело. Сейчас над Swift в Apple работает.

«топ1» - хз. Они наёмные работники мозилы. Приходят и уходят.

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

Qt не поддерживает виджиты GTK и наоборот. И ничё живут как-то.
Вообще в родной gui-библиотеке для Раста, буде такова разрабатываться, необходима поддержка в качестве бэкэнда X11, wayland, WinAPI и Mac. На первых порах.
Всё остальное не столь необходимо.

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

Автор в блоге у себя писал. Если не ошибаюсь, тупо надоело. Сейчас над Swift в Apple работает.

Детектор хипстоты зашкалил и взорвался! Продолжаю угорать с этого сообщества.

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

в качестве бэкэнда X11, wayland, WinAPI и Mac

Смотря что под этим подразумевается. winapi и cocoa позволяют клепать готовый интерфейс, в то время как X11/Wayland - только графические примитивы.

Ну и принципов построения GUI великое множество и всем нужно разное.

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

Или ты имеешь в виду что для некоторых коллекций можно сделать более эффективный reduce если миновать промежуточный итератор? сходу не могу придумать такой кейс

Для некоторых типов (например, реактивных) может быть неприменима идиома итератора, но набор фукнций filter/map/reduce/... оказывается очень полезным. Поэтому если засунуть эти функции в интерфейс итератора, то для этих типов встанет проблема необходимости реализации итерирования по ним.

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

Позволяют, да.
Но использовать в библиотеке одновременно два подхода слишком накладно.
Потому кросс-платформенные Qt и GTK рисуют всё сами.
«Пусть и безобразно, главное единообразно.»

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

Пусть и безобразно, главное единообразно.
Qt

Qt использует системную тему с переменных успехом.

Это GTK не умеет в нативную тему.

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

А в чем проблема? В том же C#, в котором LINQ привязан к итераторам (IEnumerable<T>/IQueryable<T>) можно реализовать IEnumerable<T> для чего угодно.

static IEnumerable<int> Example()
{
  for (int i = 0; ; ++i)
  {
    Thread.Sleep(1000);
    yield return i;
  }
}
static void Test()
{
  var even = Example().Where(i => i % 2 == 0);
  foreach (var i in even)
  {
    Console.WriteLine(i);
    if (i == 4)
      break; // если не добавить будет до бесконечности работать
  }
}
В Rust нет yield, но для минимального итератора вроде достаточно просто next(&mut self) -> Option<Self::Item> реализовать. В Java, кстати, ситуация аналогичная, там для поддержки стрима в простейшем случае достаточно реализовать итератор и для его реализации достаточно boolean hasNext() и T next(), то есть разницы с Rust почти нет в этом плане.

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

Ну и если нужны какие-то особые реализации всех этих filter/map и т.д., то можно их тоже определить.

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

Тут философский вопрос: стоит ли filter/map/reduce/... явным образом прибивать к итераторам. На мой взгляд, итератору ничего кроме hasNext()/next() иметь не нужно, а всю эту функциональщину лучше вытащить в extension methods/implicit conversions/functional interface. Никто не запрещает в итоге использовать в реализации filter/map/reduce итераторы (если они есть у типа). Хотя тут вот привели хороший пример когда это полезно.

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

Это для async/await, он теперь тоже в найтлях есть, кстати.

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

Ага, я даже небольшой список привел с названием соответствующих модулей/API в других ЯП

Только как минимум с Python и Ruby промахнулся.

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