LINUX.ORG.RU

Rust 1.18

 


1

10

Команда Rust анонсирует релиз 1.18.

Обновление предыдущей версии легко:

$ rustup update stable

Сам rustup можно установить здесь.

Основные изменения

Одно из главных изменений - новая версия «The Rust Programming Language», официального учебника по Rust. Он пишется открыто на Github, и имеет более ста авторов. В этом релизе включен черновик второй версии книги, имеющий 19 из 20 глав; двадцатая глава будет готова к релизу 1.19. Купить бумажную версию можно через No Starch Press. Новая версия книги полностью переписана и учитывает последние два года нашего опыта обучения Rust. Вы найдете новые объяснения основных принципов Rust, новые проекты и прочее.

В самом языке улучшено ключевое слово pub. По умолчанию, в Rust объекты приватны; можно использовать pub чтобы сделать их публичными. В Rust 1.18, pub имеет новый вариант:

pub(crate) bar;

Слово в скобках - ограничение, контролирующее степень публичности объекта. Если указанно pub(crate), то bar будет публичным для всего крейта (пакета), но не вне него. Это позволяет декларировать интерфейсы, «внутренне публичные» для пакета, но не доступные для внешних пользователей.

Также можно указать путь, например:

pub(in a::b::c) foo;

Это значит «доступно в иерархии a::b::c, но не в прочих местах».

Для пользователей Windows Rust 1.18 имеет новый атрибут, #![windows_subsystem]. Он работает так:

#![windows_subsystem(console)]
#![windows_subsystem(windows)]

Он контролирует флаг /SUBSYSTEM в компоновщике. На текущий момент доступны только console и windows. Если вы разрабатываете графическое приложение, и не указываете windows, в момент пуска программы всплывет окно консоли. С атрибутом windows этого не произойдет.

Далее, в Rust кортежи, варианты перечисляемых типов и структуры (без атрибута #[repr]) всегда имели неопределенное расположение в памяти. Мы включили автоматическое упорядочивание, которое может привести к уменьшению потребления памяти путем уменьшения необходимого выравнивания. Например:

struct Suboptimal(u8, u16, u8);

В прежних версиях Rust на платформе x86_64 эта структура имела бы размер в шесть байтов. Но согласно исходному коду, ей достаточно должно быть четырех. Остальные два байта - результат выравнивания. Поскольку мы имеем u16, он требует двух байтов. Но в данном случае, он был смещен на один байт из-за предыдущего u8. Для последнего же u8 требуется еще один байт выравнивая. В итоге, мы имеем 1 + 1 (пусто) + 2 + 1 + 1 (пусто) = 6 байтов.

Но что если структура выглядит так?

struct Optimal(u8, u8, u16);

Эта структура оптимально выравнена; u16 находится на рубеже двух байтов, как и остальная структура. Выравнивание не требуется. Это дает нам 1 + 1 + 2 = 4 байта.

При дизайне Rust мы оставили физическое расположение данных в памяти неопределенным как-раз по этой причине; любой safe-код (не следующий по «сырым» указателям) не будет затронут подобной оптимизацией. Благодаря этому, мы можем научить компилятор оптимизировать Suboptimal в Optimal автоматически. В Rust 1.18 обе структуры занимают в памяти размер в четыре байта.

Мы долго планировали это изменение; оно было и ранее в нестабильной версии Rust, но некоторые программисты писали unsafe-код, который предполагал определенное расположение данных в памяти. Если вам необходима гарантия, что физическое расположение в памяти в точности совпадает с расположением вариантов в исходном коде (например, при обращению к оболочкам Cи-кода), пометьте вашу структуру с атрибутом #[repr(C)].

Напоследок, улучшено время компиляции; например, компиляция самого rustc теперь на 15%-20% быстрее.

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

  • Child::try_wait, неблокирующая форма Child::wait.
  • HashMap::retain и HashSet::retain - версия существующего retain от Vec<T> теперь и у этих двух структур.
  • PeekMut::pop позволяет взять ранее прочитанный верхний элемент от BinaryHeap<T> без необходимости повторно упорядочивать кучу.
  • TcpStream::peek, UdpSocket::peek, UdpSocket::peek_from позволяют прочесть крайний элемент у потока или сокета.

Новый функционал Cargo

Cargo добавил поддержку системы управления версиями Pijul, который написан на Rust:

cargo new my-awesome-project --vcs=pijul

У Cargo несколько новых флагов, дополняющих --all: --bins, --examples, --tests и --benches позволяют собрать все программы указанных типов.

И наконец, Cargo теперь поддерживает Haiku и Android.

Подробнее об изменениях написано здесь.

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



Проверено: Shaman007 ()
Последнее исправление: cetjs2 (всего исправлений: 7)

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

Ну назовите какой-нибудь современный системный или околосистемный язык. А то вспомнается только какая-то древность, вроде Ada, Pascal и Modula-2, в которых читабельность все равно была повыше.

Да и разве ниша системного программирования обрекает язык на уродский синтаксис?

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

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

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

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

Ваше мнение давно «понятно и не интересно».

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

Никому не мешает, а Вам мешает.

Ну вы поспрашивайте, всем ли нравится синтаксис Rust-а, может я не один такой.

Может сначала стоит выучить Rust хотя бы на базовом уровне, прежде чем читать код?

Допустим учу, заглядываю в реальный код на Rust-е, чтобы набраться опыта и https://github.com/mersinvald/backontime/blob/master/src/backup_entity.rs#L68

|| -> Result<()> {
вижу очередное доказательство неплохой такой плотности спецсимволов на строку.

Понятно, что привыкнуть к этому можно. Понятно так же, что в процессе привыкания нужно будет приспособиться к тому, что значат || в произвольном месте текста. Что значат <()> и т.д.

Может у вас процесс привыкания был быст, но так не обязательно должно быть у всех.

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

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

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

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

Что значат <()>

() — пустой тип, пример ZST как раз, здесь используется потому что в Result не должны возвращаться данные, только ошибка.

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

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

Я согласен что код читать сложнее чем на, например, Go, где синтаксис очень простой, но там и прочитать надо будет намного больше текста.

Ну так Go до параметрического полиморфизма и не дорос.

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

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

из «современных» только Rust и есть, все что выходило недавно не является системными языками уж явно

Да и разве ниша системного программирования обрекает язык на уродский синтаксис?

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

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

Понятно, что мое мнение ничего не меняет, но все-таки не понятно, например, почему:

- люди отказались от уже устоявшихся к 2010-му году имен типов int32, uint32, int64, uint64 и т.д.;

- выбрали fn вместо func или function, равно как pub вместо public;

- используют mut вместо mutable;

- имеют & и ref;

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

Повторюсь, это уже ничего не меняет. Но осадочек...

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

- имеют & и ref;

Они для разного предназначены. При паттерн-матчинге & и ref дают разный результат.

Еще забыли Vec, &str, #[cfg()], mod, Err, impl.

С другой стороны это сильно растянет текст по ширине:

pub fn add_two(a: &mut i32) -> i32 {
// vs
public function add_two(a: mutable reference int32) -> int32 {

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

А код clang я даже не смотрел, хотя могу представить что там творится, ведь его писали люди которые знают С++

очень блин смешно. Хотя то что продумывал проект нарк сомнений нет совсем. Один файл Basic/Targets.cpp чего стоит. там описание всех архитектур, с которыми работает фронт. Всех, смекаешь? Там овер 9000 строк (9100 с хреном) и полсотни классов. И разумеется кроме как полностью клонить всю их ветку либо все время делать diff/patch и хранить патчик отцепить мух от котлет никак, что дает неописуемую радость при использовании любой vcs.

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

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

выбрали fn вместо func или function, равно как pub вместо public

первое - от ФуНах, второе - призыв вПаб.

используют mut вместо mutable

от mutt - собака. вероятно женского пола

остальное лень придумывать

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

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

Сделали мой вечер. Вам нужна подсказка, как закрыть вкладку с обсуждением и не тратить время? ;-) Или силы воли не хватает?

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

Написать несколько выражений (доступ в fs, BD, сети), которые будут выполняться последовательно, но при этом не блокировать основной поток выполнения

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

все популярные решения на которых сейчас индюшатина сидит почти все ядра в движках там на плюсах

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

тормозят все три как бешеные

Речь не о тормозах

какое то ненужно

Без PgAdmin только консоль для работы с постгресом

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

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

3 года кудахтают уже, что вот «осенью» будет файрфокс на расте

Только в этом году стал отслеживать, неужели 3 года в роадмапе пишут https://github.com/servo/servo/wiki/Roadmap и переносят из года в год? Или ты о слухах, а не об официальном роадмапе от разрабов?

файрфокс скоро вообще умрет уже

Ты недооцениваешь аникеев, которые ставят винды на компы юзеров. Сейчас они ставят хромого, ибо больше нет достойных альтернатив. Будет лиса на движке серво хотя бы на уровне хромого, думаешь аникеи продолжат бесплатно рекламировать «корпорацию добра»? Опять же вебу ненужен очередной IE6.

плохо подходит для написания бизнес логики

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

по скорости не уступят особо

Но сожрут кучу памяти или о каких решениях идёт речь (и я не о скриптоте), исключая джаву?

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

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

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

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

Но нашлись те, кто решил, что int32_t — это слишком длинно, поэтому нужно i32.

Ну вообще это действительно длинно. Суффикс _t вообще в новом языке смысла не имеет, да и в С я не совсем понимаю, зачем нужен. Почему i32, а не int32? Ну во-первых к C претензий нет, ведь, что там int, а не integer, например, т.е. 3 буквы это вполне себе читабельно, во-вторых int32/uint32 смотрится уже не так красиво, как i32/u32 (длина не одинаковая). По-моему вполне разумное решение, если бы я над этим вопросом думал, скорее всего я бы пришёл к таким же наименованиям. Можно, конечно, и подлинней сделать, может оно и лучше было бы. Всё же мне кажется, что при чтении и небольшом опыте все эти лайфтаймы будут просто отфильтровываться, всё же на логику они не влияют и интересовать они могут редко. Синтаксис у них достаточно выделяющийся, чтобы отфильтровывать его на автомате.

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

Ну вот в .NET-е используются Int32 и UInt32. И привычно (легко узнается на базе C-шного опыта), и нет унаследованного из C суффикса.

По поводу i32. Вам, наверное, мало приходилось видеть кода от хардкорных математиков. Когда они реализуют сложные вычисления, там полно i, ii, j, jj, kk, i1, i4, i12, j24, k30 и тому подобных имен переменных. Причем, что интересно, далеко не всегда такие названия можно заменить на что-то осмысленное.

В общем, к чему я это: есть «правило наименьшего удивления» (least surprise principle), которое разработчиками Rust-а было нарушено при выборе имен вида i32/u32.

int32/uint32 смотрится уже не так красиво, как i32/u32 (длина не одинаковая)

Зачем вам одинаковая длина для имен типов? Практический смысл в этом какой?

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

По поводу i32. Вам, наверное, мало приходилось видеть кода от хардкорных математиков. Когда они реализуют сложные вычисления, там полно i, ii, j, jj, kk, i1, i4, i12, j24, k30 и тому подобных имен переменных.

Нахрен они мне в моём раст-коммунити? Пускай дальше говнокодят на матлабе.

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

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

|| -> Result<()> {

Элементарно Ватсон, в самой первой книжке о синтаксисе говориться, что

  • || - это замыкание
  • -> - эти знаки указывают, что замыкание возвращает следующее значение
  • Result<()> - это Enum включающий в себя обобщённый тип

Ваша критика на уровне 7-и классника который первый раз в жизни увидел бэйзик, без обид, но серьёзно =) Нельзя придираться к таким элементарным вещам, просто потому что Вы не можете догадаться как они работают. После прочтения доки, эти символы не вызывают боли, я это гарантирую =)

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

В общем, к чему я это: есть «правило наименьшего удивления» (least surprise principle), которое разработчиками Rust-а было нарушено при выборе имен вида i32/u32.

Как-то натянуто получается. i32/u32 - это то, что используется всегда, после прочтения 2х хелллоуворлдов новичок уже знает значение этих слов. Да и без объяснения, догадаться что есть i32 несложно. Наименьшее удивление - это когда ты вроде уже всё знаешь, а потом в каком-нибудь малоизвестном случае действуешь в соответствии с привычкой и получаешь что-то сильно нелогичное.

i32 - это как до современных потомков плюсов докопаться, что у них массив не int array[], а int[] array.

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

Во-первых, я понимаю, как это работает. Блого, раст не первый язык с лямбдами.

Во-вторых, не вижу как ваше пояснение отменяет факт высокой плотности спецсимволов на строку кода.

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

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

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

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

пока твои аникеи узнают про файрфокс компанию уже прикроют, ибо скоро у файрфокс будет 1% пользователей = нет дохода от рекламы = мозилле конец, других источников дохода у них нет, а как ты думаешь что будет со спонсированием разработки раста?

Но сожрут кучу памяти или о каких решениях идёт речь (и я не о скриптоте), исключая джаву?

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

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

- люди отказались от уже устоявшихся к 2010-му году имен типов int32, uint32, int64, uint64 и т.д.;

А в LLVM числа тоже имеют наименование i32, u32 и т.д. Это тоже устоявшиеся значения и что теперь?

- выбрали fn вместо func или function, равно как pub вместо public;

Это совсем субъективно, мне нравиться fn и pub и вообще не понимаю зачем полные и длинные имена нужны?

- используют mut вместо mutable;

ЗАЧЕМ?! Просто представьте какой ужас станет с кодом

 public function backup(&mutable self, path: &mutable String) -> Result<()> {
Вот уж точно ужас, два параметра на половину экрана, другое дело:
 pub fn backup(&mut self, path: &mut String) -> Result<()> {
Очевидно, что второй вариант легче читается и уж точно быстрее написать

- имеют & и ref;

Ну тут хрен знает, может кто-то подскажет?

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

Не вижу ни чего плохо

AntonyRF ★★★★
()

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

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

Во-вторых, не вижу как ваше пояснение отменяет факт высокой плотности спецсимволов на строку кода.

Это субъективное восприятие, мне, например, после прочтения документации не вызывало жжения от синтаксиса. Если для Вас понимание оного не меняет его восприятия, то думаю, что ни кто Вам не поможет ¯\_(ツ)_/¯

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

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

Конечно субъективное. Мне читать Rust-овый код тяжелее, чем код на других языках. Я пояснил почему. Очевидно, что никто не обязан разделять мою точку зрения.

Мне интересно другое: в чем Rust-оманы пытаются меня убедить?

В том, что у Rust-а хороший и приятный синтаксис? Это не так.

В том, что к синтаксису Rust-а можно привыкнуть? Так в этом нет сомнения.

Привычка, однако, не отменяет того, что синтаксис у Rust-а корявый и придумывали его те, кто хочет экономить на спичках и писать:

pub fn backup(&mut self, path: &mut String) -> Result<()>
вместо
public func backup(self mutable ref, path mutable ref String) Result<_, Err>

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

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

Смущает. Без лидирующих квадратных скобочек хотелось бы обойтись. А вот ()-> в принципе согласуется с синтаксисом лямбд в других языках.

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

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

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

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

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

В каких языках, кстати? Если не брать всякую экзотику, лямбды появились в C++, C#, Java и Rust примерно одновременно. Глупо подстраиваться под подход, который в другом языке экспериментальный, равно как и менять свой синтаксис потому что в соседнем языке фича стабилизировалась раньше. Ну и на тему least surprise: вас почему-то смущают квадратные скобки, которые нужны, но плохо, потому что оно не так как принято в других языках, но не смущает ->double, которое не так, как принято в этом языке. Если уж бороться за чистоту и least surprise, то пусть бы оно было [] double() {...}

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

лямбды появились в C++, C#, Java и Rust примерно одновременно

К счастью, этим множество языков программирования не исчерпывается. Лямбды в Scala, насколько я помню, появились гораздо раньше начала работ над Rust-ом.

Ну или вот очень похожий на Rust синтаксис лямбд в Ruby, но там лямбды обрамляются:

do |a, b| ... end
{ |a,b| ...}
И как по мне, так это гораздо лучше |a, b| ...

но не смущает ->double, которое не так, как принято в этом языке

Вы, вероятно, не в курсе синтаксиса auto f() -> R.

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

да я уже наблюдаю как они интегрированы.

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

молодцы растаманы.

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

Ну и по поводу C#:

Lambda expressions provide a concise way to write first-class anonymous function values. Compare the following C# 2.0 snippet:

listOfFoo.Where(delegate(Foo x) { return x.Size > 10; });
with this C# 3.0 equivalent:
listOfFoo.Where(x => x.Size > 10);

С# 3.0 — это 2007-ой год. Ни C++11, ни Rust еще нет на горизонте.

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