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)

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

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

скриптовый движок нам сразу дает раст везде? или ты о чем?

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

Давно программы на плюсах стали оптимизированние программ на ассемблере? Тогда где движки на ассемблере?

с тех пор как можно 1) делать вставки на ассемблере если нужно 2) игровые движки должны запускатся на куче платформ

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

Сейчас есть проблема со встраиваемыми языками: для них надо экспортировать C ABI, а это ансейф.

Такой язык позволил бы сделать интероп не выходя из Safe Rust и не лишаясь гарантий.

Не то чтобы я вижу большой смысл, просто мысли вслух

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

Но то, что делают они, ни вы, ни я не запрограммировали бы.

Если уж так часто надо копаться в их говнокоде, то этот говногод и причесать можно.

Да, бывает, что большие формулы из нескольких десятков составляющих разбивают на отдельные части, вычисляют их, а потом объединяют в единое целое.

Ну и зачем тебе лазить по определению формулы? Или платят тебе, а пишут за тебя?

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

С учетом того, что || в Rust это и OR, и начало лямбды без аргументов, мне так не показалось.

Ты принял это за логическое утверждение?

дочитать тему до конца

Если мне будут платить за время проведённое тут, то да.

что уже давным-давно обсудили?

Я не имею права высказать своё мнение?

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

Потому, что с высокой долей вероятности вы ничего об Eiffel-е не знаете.

Аргументный аргумент. Т.е. чтобы сказать нравиться мне синтаксис или нет - мне надо выучить весь язык? Но Вы то с Растом так не поступили -_-

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

Ну ок, пусть будет ООП-отстой. Хоть я про это и не сказал.

Перепишите его с помощью процедурного подхода, может мнение об исследованиях IBM для аж 19-ти проектов, у вас и поменяется.

Нельзя переписать ПРОСТО любой код. Даже с ООП на ООП. Даже без ООП на другой язык программирования без ООП. Примеров навалом, GTK-doc когда переписывали с perl на python выкатили свои страдания в статье. Даже с того же самого языка на тот же самый язык проект не переписать просто, потому что само по себе переписывание будет занимать много сил, у же не говоря что будут трудности в конвертации представлений из ООП в процедурщену. Но и в обратную сторону код с процедурного стиля переписать в ООП тоже сложно будет. Проблема не в том, что какая-то сторона ущербна, а в том что они разные и всё.

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

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

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

Например, имея структуру, скажем, из указателя и количества элементов (полученную из ffi, как вариант) можно в реализовать выборку элемента по индексу с проверкой, что индекс меньше количества, где будет offset + raw pointer deref (unsafe). В другом же safe методе нечаянно поменять переменную с размером. Получим ошибку вызванную safe кодом.

При должной инкапсуляции и обеспечении инвариантов на границе модуля получается ограничение области «действия» небезопасного кода модулем.

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

Аргументный аргумент. Т.е. чтобы сказать нравиться мне синтаксис или нет - мне надо выучить весь язык? Но Вы то с Растом так не поступили

Есть у меня ощущение, что про Rust я знаю, скажем так, в разы больше, чем вы про Eiffel. И документацию по Rust-у я читал (не штудировал, но читал), и hello_world на Rust я запускал, и с lifetimes и borrow checker-ом разбирался.

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

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

Подробнее плиз

Объявил один раз метод для суперкласса и в любом дочернем он уже доступен. И не нужно было писать вот так Наследование в Rust (комментарий)

То есть impl Shape for CircleData не нужна, если есть impl Shape for ShapeData. И вообще отказаться от необходимости описывать отдельно trait, struct, impl. Если уже есть, то извиняюсь, не видел.

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

Ты принял это за логическое утверждение?

Скажем так, был сильно удивлен сочетанию || и ->, поскольку раньше с таким не сталкивался.

Я не имею права высказать своё мнение?

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

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

{ |args| body }
do |args] body end
->(args) { body }
Хотя про последний узнал совсем недавно. Можете привести пример лямбды в Ruby без окружающих ее {} или do-end?

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

Только в ваших домыслах. Я выбрал такую стратегию обработки ошибок осознанно, исходя из задачи.
Будь это библиотека для других людей — была бы другая стратегия.

Что ты опровергаешь? Ты же только подтверждаешь мои «домыслы».

Это и есть он, хорошо работающий в конктерном случае, в конкретной утилите.

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

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

А я, конечно же, просто так это сделал, без профилировки и бенчмарков, по вашему?)

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

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

https://habrahabr.ru/post/322256/

Смешно же во всей этой чепухе вокруг null то, что это не работает. Я уже почти смирился с писаниной бездарной клинописи в своем коде с надеждой, что «зато когда-нибудь это спасет».

Ага, щаз.

Java

public class jHelper {
  public static jHelper jF() { return null; }
  public void M() {}
}

Kotlin

fun F() {
  val a = jHelper.jF()
  a.M()  //Упс!
}
NextGenenration ★★
()
Ответ на: комментарий от baist

У меня в плюсовом коде тоже самое и в примерах неинициализированные переменные.

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

Посмотри еще, я тебе отписал про баг с shm.

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

или ты о чем?

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

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

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

Потому, что с высокой долей вероятности вы ничего об Eiffel-е не знаете.

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

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

с тех пор как можно 1) делать вставки на ассемблере если нужно

И часто это нужно?

2) игровые движки должны запускатся на куче платформ

Вот появится необходимость к примеру в многопоточности, появится повод. Или сейчас не нужна многопоточность?

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

Скажем так, был сильно удивлен сочетанию || и ->, поскольку раньше с таким не сталкивался.

Мир прекрасен и удивителен. Когда со следующим удивительным столкнётесь, не спешите паниковать.

Можете привести пример лямбды в Ruby без окружающих ее {} или do-end?

Разве я говорил что лямбды в них совпадают полностью?

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

Мой юный друг, не вы ли в разговоре про лямбды в Ruby давеча написали:

Для однострочных лямбд открывающие скобки ненужны.

Если это были вы, то не составит ли вам труда привести пример оной лямбды-однострочника в Ruby?

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

И часто это нужно?

если это нужно не часто, то видимо поэтому и не пишут? уже написали все на плюсах

Вот появится необходимость к примеру в многопоточности, появится повод. Или сейчас не нужна многопоточность?

плюсы не могут в многопоточность?

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

Если это были вы, то не составит ли вам труда привести пример оной лямбды-однострочника в Ruby?

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

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

Тут понимаешь с мат софтом боль и в C т.к большинство кода на фортране, а то что не на фортране — код прогнаны через f2c. Писать биндинги для раста нафиг надо. Проще прогнать через f2rs и тут боль с i32

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

но что в c# что в rust в однострочных лямбдах фигурные скобки не нужны.

Сударь, я говорил о том, что не смотря на похожесть лямбд в Ruby и в Rust-е, лямбды в Ruby для меня удобнее тем, что там всегда есть отрывающая { или открывающий do. И тут вы такой про лямбды в C# и Rust. С хрена ли? Голову забыли включить или, по юности лет, развитие мозга еще не закончилось?

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

У математиков есть привычка создавать функции с именами типа i32?

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

Тем что в kotlin нужен лишний синтаксис для проверки на null, который порой не помогает если нужно

так в твоем примере нету никакого синтаксиса для проверки на null ;) а то что он автоматически такое сейчас не ловит - ну сорян, отпишы в багтреке

Это к тому что kotlin не идеал.

а что идеал? есть просто разные степени неидеальности

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

То есть твоя позиция такая: rust не удобен так как в однострочных лямбдах отсутствует открывающая и закрывающая скобки? И если б они были, то код внезапно стал понятнее?

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

так в твоем примере нету никакого синтаксиса для проверки на null ;)

Он будет в несколько других вопросах.

а то что он автоматически такое сейчас не ловит - ну сорян, отпишы в багтреке

говорят что раньше он действительно проверял, но потом пргерам надоело писать проверки на котлине и они отключили.

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

плюсы не могут в многопоточность?

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

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

где эти движки то на расте? делаешь уже?

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

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

плюсы не могут в многопоточность?

Как бы нет.

Давай, Разорка, жги правду-матку напалмом! Градус идиотии в этой теме еще недостаточно высок, не все покровы еще сорваны!

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

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

Пойдите еще прикопайтесь к асинхронному коду на C++, ей богу.
Есть библиотеки для рантайма и зеленых потоков, есть даже экспериментальный GC, а есть tokio и futures, которые предоставляют асинхронные примитывы без многопоточного планировщика, и я использую второй вариант.

В чем ваша проблема?

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

Я об обратном - если у вас *уже* есть строка на куче, принимать ее там, где требуется слайс.

Это тоже вряд ли. Ведь некоторые арифметические касты вполне безопасны, например, из u8 в u32, но язык и это требует делать явно.

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

Легкие потоки тащат с собой рантайм, тут же рантайма нет и потому и планировщик написан руками.

А чего ты в таком случае tokio и futures руками не написал? Написал бы руками и гордился. А то можно подумать, что твой костыльный планировщик - не рантайм.

В чем ваша проблема?

Не моя, а твоя. Ты притащил пример кода, чтобы похвастаться, а хвастаться там нечем.

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

Завязывайте прикапываться к выдернутым из контекста фразам. Что в «упростить разработку многопоточного кода в сравнении с C++» не понятно?

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

А чего ты в таком случае tokio и futures руками не написал? |

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

Не моя, а твоя.

Нет, у меня нет проблем.

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

Что в «упростить разработку многопоточного кода в сравнении с C++» не понятно?

Не понятно, как из «Мозилла спонсирует раст, чтобы упростить написание многопоточного кода в лисе» следует «плюсы не могут в многопоточность».

Плюсы давным-давно могут в многопоточность, даже до появления std::thread в стандарте. Так что, как минимум, речь может идти только о сравнительной стоимости. Как максимум — об адекватности решения самой Mozilla о разработки целого языка для перевода своего однопоточного браузера с плюсов на многопоточный на Rust-е.

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

Могут виснуть а могут и не виснуть.

Вы еще скажите, что Rust кроме отсутствия data races еще и гарантирует отсутствие deadlock-ов.

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

Поставим вопрос по другому: что из того что гарантирует раст гарантируют кресты?

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

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

А «ерунда» говорит о том что у инди-студий без денег хватает мотивации разрабатывать движок и игру на Rust, причем довольно активно.

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

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

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