LINUX.ORG.RU

Rust 1.15

 


2

10

Представлен релиз Rust 1.15 — системного языка программирования, нацеленного на безопасную работу с памятью, скорость и параллельное выполнение кода. В этот релиз вошли 1443 патча.

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

$ rustup update stable
или же следуя инструкции на соответствующей странице.

Стабильная версия, наконец-то, увидела долгожданную возможность: пользовательские расширения (custom derive)! К примеру, в Rust вы всегда могли автоматически реализовать некоторые типажи через атрибут derive:

#[derive(Debug)]
struct Pet {
    name: String,
}
В примере выше была определена реализация типажа Debug для структуры Pet с использованием минимального кода. Однако, это работало только для тех типажей, которые являлись частью стандартной библиотеки; пользователям это было недоступно. С версии Rust 1.15 это стало доступно. Это значит, что если вы захотите преобразовать структуру Pet в JSON, это так же просто, как добавить Serde в ваш Cargo.toml:
[dependencies]
serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9" 
и добавить новый типаж к Pet:
#[macro_use]
extern crate serde_derive;

extern crate serde_json;

#[derive(Serialize, Deserialize, Debug)]
struct Pet {
    name: String,
}

fn main() {
    let pet = Pet { name: String::from("Ferris") };

    let serialized = serde_json::to_string(&pet).unwrap();
    println!("serialized = {}", serialized);

    let deserialized: Pet = serde_json::from_str(&serialized).unwrap();
    println!("deserialized = {:?}", deserialized);
}
Это выведет:
serialized = {"name":"Ferris"}
deserialized = Pet { name: "Ferris" }
Другой часто используемый вариант — Diesel (новая версия 0.10.0 которого представлена вслед за Rust 1.15). Допустим, у нас есть база данных, состоящая из Pet. Мы можем сделать выборку следующим образом:
// some extern crate and use lines elided here

#[derive(Queryable)]
struct Pet {
    name: String,
}

fn main() {
    use diesel_demo::schema::pets::dsl::*;

    let connection = establish_connection();
    let results = pets
        .limit(5)
        .load::<Pet>(&connection)
        .expect("Error loading pets");

    println!("Displaying {} pets", results.len());
    for pet in results {
        println!("{}", pet.name);
    }
}
Другие примеры с использование Diesel можно посмотреть на сайте.

Такого рода библиотеки являются очень мощными, но полагаются на пользовательские расширения для эргономики. Хотя эти библиотеки и работали прежде на стабильной версии Rust, пользоваться ими было не так удобно, и пользователи предпочитали работать на ночных версиях Rust «из-за Serde и Diesel». Пользовательские расширения являются одними из самых широко-используемых возможностей в ночных версиях Rust. Таким образом, в июле прошлого года была начата работа над RFC 1681 для реализации данной возможности. В августе RFC был принят, претерпел большое количество работы и тестирования и, в итоге, был включен в эту стабильную версию.

Научиться писать свои собственные расширения можно в соответствующей главе книги «The Rust Programming Language».

Хотя больше всего упоминаний в рамках данной возможности пришлось на «Serde и Diesel», есть много других крутых возможностей, которые можно делать при помощи пользовательских расширений: например, derive-new. Ещё больше можно увидеть, посмотрев список обратных зависимостей пакета syn. (syn очень важен для написания пользовательских расширений; для большей информации, смотрите соответствующую главу книги, ссылка на которую приведена выше). Пользовательские расширения были так же известны под названием «макросы 1.1», так как включают в себя основополагающую инфраструктуру для поддержки ещё более мощных возможностей во время компиляции в Rust, под названием «макросы 2.0». Ожидаем услышать больше новостей в этой сфере в будущих релизах.

Другие улучшения

Система сборки Rust была переписана на Rust с использованием Cargo. Теперь это основная система. Процесс был долгим, но наконец-то принес свои плоды. Вся разработка Rust происходит в основной ветке с использованием новой системы сборки, начиная с декабря прошлого года и показывает хорошую работу, ещё один показатель зрелости Cargo. Уже подготовлен PR для полного удаления всех Makefile-ов к версии Rust 1.17. Это позволит rustc напрямую использовать пакеты с crates.io в компиляторе, как это делается в других проектах на Rust.

В Rust появилась поддержка новых платформ 3 уровня: i686-unknown-openbsd, MSP430, и ARMv5TE.

Компилятор получил ряд улучшений производительности. Работы над производительностью компилятора продолжаются от релиза к релизу и в будущем ожидаются ещё больше улучшений.

В качестве незначительного улучшения, ?Sized теперь можно использовать в утверждении where. Другими словами:

struct Foo<T: ?Sized> {
    f: T,
}

struct Foo<T> where T: ?Sized {
    f: T,
}
Вторая форма теперь принимается, и равнозначна первой.

Более подробный список изменений.

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

Алгоритм slice::sort был переписан и теперь гораздо-гораздо быстрее. Применяется гибридная сортировка слиянием, вдохновленная Timsort. Раньше применялась простая сортировка слиянием.

Если у вас имеется Vec<T> где T: Copy с вызовом extend на него, ваш код теперь будет гораздо быстрее.

Говоря о быстродействии, chars().count(), chars().last(), и char_indices().last() теперь тоже быстры!

Китайские символы теперь правильно отображаются в fmt::Debug.

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

Более подробный список изменений.

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

Cargo теперь будет выдавать предупреждение, если в верхнем уровне пакета будет файл с названием build.rs, но не будет аннотации build = "build.rs". Это делается из соображения совместимости, так как предполагается использование файла build.rs в верхнем уровне пакета в качестве файла сборки.

В этом релизе, скрипты в Cargo больше не имеют доступа во время сборки к переменной среды окружения OUT_DIR через env!(«OUT_DIR»). Теперь проверку переменной надо осуществлять во время выполнения через std::env. Установка значения переменной во время сборки было ошибкой и некорректной при кросс-компиляции. Проверьте свои пакеты и обновите на использование std::env.

Команда cargo test получила поддержку флага --all, что полезно при работе с рабочими пространствами.

Появилась возможность статической компиляции с использованием MSVC CRT на Windows, и статического связывания OpenSSL на Mac OS X.

Более подробный список изменений.

Страница благодарности

Для выражения благодарности авторам и помощникам, которые делают Rust лучше, запущена новая инициатива «Thanks!» — страница с благодарностью людям, которые внесли вклад в Rust. Страница доступна по адресу https://thanks.rust-lang.org/ (или https://♥.rust-lang.org). Список авторов и помощников за всё время, по количеству коммитов, можно посмотреть здесь: https://thanks.rust-lang.org/rust/all-time. В Rust 1.15 всего был сделан вклад со стороны 137 людей.

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

★★★★★

Проверено: jollheef ()
Последнее исправление: Deleted (всего исправлений: 2)

Ответ на: комментарий от makoven

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

Или асинхронщина выйдет из моды.

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

Не совсем точно выразился. Под асинхронщиной я имел в виду так же и акторы и CSP. А из моды оно выйдет со смертью линукса, и если в ОС, что придет ему на замену, будут легкие треды

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

А из моды оно выйдет со смертью линукса, и если в ОС, что придет ему на замену, будут легкие треды

Что теоретически решают задачу горизонтального параллелизма, но никак не решают задачу неблокирующего ИО.

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

Если можно создавать треды тысячами без жора памяти, то пущай блокируются. Будут те же акторы, только на уровне ОС

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

https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html

А, вы про каналы, которые не n:m. Ну так-то все верно. Мой прокол в терминологии

И да, нити ОС можно создавать тысячами. Или десятками тысяч

Зачем тогда hyper добавили futures? Если уже было рабочее решение на тредах

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

Если можно создавать треды тысячами без жора памяти, то пущай блокируются.
Зачем тогда hyper добавили futures? Если уже было рабочее решение на тредах

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

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

А, вы про каналы, которые не n:m. Ну так-то все верно.

CSP в изначальном понимании вообще подразумевает каналы 1:1.

Зачем тогда hyper добавили futures? Если уже было рабочее решение на тредах

Мода^WМаркетинг.

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

Нипанятна. Можно на примере?

Ну я вижу два примера многопоточности.

Первый - «горизонтальный». Допустим, задача отсортировать массив в миллион элементов. Можно разбить его на четыре части, каждую отсортировать отдельным тредом, а потом скомбить по алгоритму merge-sort. Классический divide-and-conquer. В графике, так вообще можно отдельно рендерить каждый пиксель, чем успешно пользуется графическая карточка, по сути представляющая собой массив большого количества примитивных процессоров, работающих параллельно.

Другой же - «вертикальный», где целью является не столько параллелизм, сколько неблокировка. Допустим, юзер тыкает на кнопку «сохранить объект». Мы не блокируем всю программу, а сразу возвращаем сообщение «сохранение началось», при этом запускаем процесс сохранения, обернув его в future, задав инструкцию «когда закончишь, выведи на экран сообщение, что все сохранилось успешно».

Последний пример можно реализовать хоть тредами, хоть процессами, но future более эргономичный и позволяет задать нужные колл-бэки в момент запускания, избавив программиста от мороки самому отслеживать прогресс тредов и реагировать на их завершение. Так же удобно комбинировать несколько futures которые должны действовать одни за другим, по принципу pipeline вместо огромного количества вкладок if/else.

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

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

Но, согласитесь, акторами или каналами* выходит красивее, чем колбеками (слово ПТСР-триггер js-разработчика). Причем решение обеих задач

* если они в синтаксисе языка

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

С ваших слов выходит, что nginx, lighttpd под воздействием моды выбрали евентлуп вместо тредов с урезанным стеком

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

Но ведь с go это действительно легко

Потому что единственная цель Go - сделать это легким.

rust подкачал

Кого? Rust - язык системного программирования. Он бы подкачал, если бы связался с нетривиальным рантаймом.

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

Потому что единственная цель Go - сделать это легким

Согласен. Гугл понимает, что проблема актуальная. В Rust не понимают

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

Можно было бы сделать асинхронщину или n:m если не в стдлибах, то хотябы отдельной репой в rust-lang. Тогда бы все желающие строили свои поделки на единой кодовой базе. А судя по текущей ситуации, нас ожидает разброд и шатание

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

Гугл понимает, что проблема актуальная. В Rust не понимают

Go - простой тупой язык (нативный Python) для индусов, основная задача которых - генерировать JSON. Rust - сложный язык с высоким порогом входа для системного программирования - области, у которой сам по себе высокий порог входа.

Можно было бы сделать асинхронщину или n:m если не в стдлибах

Не знаю, что на этот раз ты называешь «асинхронщиной», но, с технической стороны, опыт показал, что green threads сделать было нельзя. С менее технической стороны, ресурсы Мозиллы несравнимы с ресурсами Гугла, так что Мозилла не может забивать свое решение в чужие глотки.

нас ожидает разброд и шатание

Увидим. Пока, насколько я могу судить, взлетает tokio. Потому что это гораздо больше, чем асинхронность.

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

А судя по текущей ситуации, нас ожидает разброд и шатание

В зависимостях tokio-core имеется mio. По-моему, всё вполне согласованно развивается.

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

В зависимостях tokio-core имеется mio. По-моему, всё вполне согласованно развивается.

Или же костыль для совместимости :-)

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

Или же костыль для совместимости :-)

Да тебе-то откуда знать...

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

Сделать можно и на php. Вопрос в сроках, объеме кода и прочих вещах. И потом очень часто за деревьями можно не увидеть леса. На практике так обычно и происходит.

Akka-стримы хороши, скажем, при обработки сложных запросов REST, особенно, если это вовлекает в себя несколько серверов.

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

под лесом я обычно понимаю решение задачи, а под деревьями - способ ей решения. и во стримами вероятно можно словить оргазм в стиле The Incredible Machines что вот эта вся конктрукция ещё и работает (вроде бы). а как она будет обрабатывать невалидные ответы (например, оборванный посередине json), как это всё будет поддерживать не автор решения - из документации непонятно. а опыт работы с node.js показывает что за деревьями асинхронщины, раскиданной по разным обработчикам скрывается очень плохая диагностика ошибок и проблемы с пониманием (решение получается постичь только целиком, а не по частям, ну или с тоннами временных диагностических записей в лог), а зачастую и ужасная производительность (не путать с масштабируемостью). да и тот же message-passing через JMS то ещё удовольствие в сопровождении или постижении того как оно вообще работает. но старушки кушают.

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

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

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

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

Мне показалось, что akka streams - это по сути кондуиты, но попав на ниву Java, красивая идея из мира Haskell получилась несколько неказистой, как это обычно бывает. Только на Java и .NET ничего лучше и нет

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

>...есть ли под него нормальные средства разработки с автодополнением и поддержкой рефакторинга?

Есть неплохой модуль для Идеи.

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

Mio - это абстракция над epoll/kqueue/костылем для винды Tokio - это обертка из futures-rs вокруг Mio

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

В Rust не понимают

Божечки... Все ваши претензии сводятся к тому, что rust не подходит лично вам.

Мне вот эти каналы и вебдев вообще до одного места. Он мне не нужен в std.

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

Знание его не отменяет необходимости знать ерланг

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

И что-то меня терзают смутные сомненья, что количество Rust-программистов вырастет до сотен тысяч.

не вырастет
это язык для системных программистов, коих всегда было меньшинство
вы попробуйте реализовать связный список на расте - см. http://cglab.ca/~abeinges/blah/too-many-lists/book/README.html
и поймете, что язык нетривиален

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

А может это новый тренд. Выкидывать интерпретаторы и языки-виртуальные машины, и переходить на современные компилируемые языки с минимальным оверхедом (go, swift, rust)

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

Erlang и Go позволяют держать тысячи коннекшонов при минимальном потреблении памяти и не сжирая проц на переключениях контекста

Тысячи, но не миллионы. Чудес не бывает.

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

Вручную или автоматически построенный автомат и event loop дадут гораздо больше.
Горутины хоть и легковесные, но все равно треды со своим стеком и контекстом. И переключения контекста там никуда не делись, просто они быстрее из-за отсутствия необходимости уходить в kernel-mode при переключении

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

Erlang и Go позволяют держать тысячи коннекшонов при минимальном потреблении памяти и не сжирая проц на переключениях контекста

Тысячи, но не миллионы.

Всего тысячи? Тогда это как-то... бессмысленно. Я всё же читал, что Erlang позволяет то ли десятки тысяч, то ли миллионы.

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

Ты уже большой мальчик, а в сказки веришь. Миллионы можно получить только на пачке серверов. Десятки тысяч - да. Но небесплатно. Сотни тысяч разве что процессов-бездельников. В beam-машине всё еще не идеально реализована работа на многопроцессорных серверах: недавние тесты показали, что core i5 с четырьмя потоками может выдать большую производительность, чем Xeon на 16. И еще, что тот же Xeon показывает ровно ту же производительность при ограничении beam-машины 4 ядрами.

ЗЫ. Вышеприведенное относится к эрлангу. Аналогичных тестов для go я не видел.

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

Миллионы можно получить только на пачке серверов.

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

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

Тогда это как-то... бессмысленно.

Несмотря на прошлые 2 моих поста, это имеет смысл. В эрланге очень хорошо работает концепция let it crash, поскольку поднять новый процесс взамен погибшего очень дешево. Всё таки телеком работает над тем, чтобы несмотря на ошибки, разговоры продолжались.

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

Ты уже большой мальчик, а в сказки веришь.

Не будем обсуждать, кто во что верит.

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

Сотни тысяч разве что процессов-бездельников.

Естественно. Вообще весь хайп о легковесных процессах построен вокруг IO-bound задач, где почти все процессы висят на ожидании I/O.

недавние тесты показали, что core i5 с четырьмя потоками может выдать большую производительность, чем Xeon на 16

Пускаешь 4 VM на сервере и получаешь миллион процессов на одной машине. И пойнт в том, что миллион «родных» нитей будет как минимум стоить дороже, если ядро вообще их потянет.

Несмотря на прошлые 2 моих поста, это имеет смысл. В эрланге очень хорошо работает концепция let it crash

Это ортогонально нативности нити. В Rust можно сделать let it crash^Wpanic, в Си++ - let it throw.

Пойнт в том, что Erlang и Go, видимо, дают что-то, невозможное на нативных нитях.

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

Вообще весь хайп о легковесных процессах построен вокруг IO-bound задач, где почти все процессы висят на ожидании I/O.

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

Пускаешь 4 VM на сервере и получаешь миллион процессов на одной машине. И пойнт в том, что миллион «родных» нитей будет как минимум стоить дороже, если ядро вообще их потянет.

Имеет право на жизнь. Только RAM еще докинуть.

Это ортогонально нативности нити. В Rust можно сделать let it crash^Wpanic, в Си++ - let it throw.

Нет инфраструктуры OTP, без которой эрланг не нужен. Так-то brainfuck тьюринг полный и на нем тоже много чего можно.

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

Пойнт в том, что Erlang и Go, видимо, дают что-то, невозможное на нативных нитях.

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

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

Всего тысячи? Тогда это как-то... бессмысленн

Видать-таки не бессмысленно, если глянуть сколько Макс Лапшин берет за месячную подписку)

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

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

Dark_SavanT ★★★★★
()
Последнее исправление: Dark_SavanT (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.