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)

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

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

Так а причем тут .to_owned тогда? А вообще в обратную сторону и так работает, &String неявно приводится к &str.

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

Так а причем тут .to_owned тогда? А вообще в обратную сторону и так работает, &String неявно приводится к &str.

А String к &str не приводится. Тут блог пост про это, в заголовке «implied borrows»

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

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

Помоему Niko Matsakis говорил что implied borrows раньше был в языке но они эту фичу отменили, потому что ухудшается читаемость кода.

pftBest ★★★★
()

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

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

А String к &str не приводится.

Через дженерики - приводится:

fn stuff<S: AsRef<str>>(text: S) {
    let t: &str = text.as_ref();
    println!("{}", t);
}

fn main() {
    let text1: &str = "text";
    let text2: String = "text".to_owned();

    stuff(text1);
    stuff(text2);
}

Еще пример - почему нет неявного ап-каста u32 туда, где нужен u64, итп?

Слишком хитрое, неявное поведение.

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

А в строку оно тоже печатать умеет? ) я к тому это писал что есть язык в котором все операции вывода делаются 1 оператором.

Про макросы ввода вывода в расте знаю, по мне так либо 1 оператор на все либо зоопарк функций как в C

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

или с утилитой, которая сейчас работает в проде

Что в глаза с ходу бросилось. Мне, помнится, кто-то рассказывал, что unwrap() - это для всяких там поделок, а в проде, мол, нужно ошибки обрабатывать честно. Нет, оказывается. Или установки поменялись?

Асинхронный резолвер... на куче потоков! Серьёзно? Я, конечно, тоже писал подобное для прода, но мне конкретно этот кусок стыдно было бы показывать, потому что если бы у меня было на несколько дней больше, сделать это стоило на сопрограммах. А здесь я даже не вижу, чтобы потоку выставлялся минимальный размер стека.

asaw ★★★★★
()

Этот поток растоновостей напоминает ПМС студию на хабре.

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

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

Ну да, там, где в других языках была бы обработка исключений без всяких финтов, в расте нужны финты. А исключений не будет чисто по религиозным соображениям, хотя «под капотом» они будут использоваться для той же паники в unwrap()...

asaw ★★★★★
()
Ответ на: комментарий от RazrFalcon
fn stuff<S: AsRef<str>>(text: S) {

вот из-за такого, с позволения сказать, синтаксиса это чудо в перьях в массы не пойдёт. А эти 100500 ссылок, врапперов итд. Кому-то это правда нравится?

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

А при чём тут аналитика? Я это распарсить не могу и не захочу.

Это объявление действительно кому-то нравится? Я серьёзно спрашиваю.

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

Магические касты не способствуют снижению порога входа, скорее наоборот.

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

Нашел твой второй баг, у тебя XShmSegmentInfo перемещается когда ты его ложишь в Data, и от этого меняется его адрес в памяти. Чтобы так не происходило нужно его положить на кучу.

struct Demo
{
	xshm_segment_info: Box<xshm::XShmSegmentInfo>,
        ...
}
...
let mut xshminfo = Box::new(Self::create_xshm_sgmnt_inf(
            (w * h * 4) as usize).unwrap());

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

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

А тебе лень лишний амперсанд написать?

Лень. А еще больше лень запоминать, какие функции требуют слайс, а какие - строку, если у меня уже и так строка.

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

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

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

Вот это вообще что за ах?

(w * h * 4) as usize).unwrap()

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

=====

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

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

И как же по мнению экспертов его сделать более выразительным? Заменить mut на mutable как в окамле? Заменить Box::new на неявный оператор new, который можно перегрузить как угодностями и вызываться будет что угодно как в плюсах? Добавить сливающиеся с кодом сишные касты или уродство на 20 символов из плюсов? Заменить :: в статических ф-ях на \ из пхп?

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

Да это вообще концентрированное нечто. Что за Box и зачем он нужен? Что за Self? Что за враппинги-шмаппинги? Этого кода вообще не должно быть. Это всё - какой-то набор фарша для компилятора. Если не ошибаюсь.

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

А то, что << может значить побитовый сдвиг влево, вывод в поток или две угловые скобки, не внушает? Ну так и тут: ':' имеет несколько значений.

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

Ну, вы видимо и перед пейсанием на сях тоже ни одной книжки не читали? Просто сели и на те — читается как ингришь?

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

anonymous
()

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

Они про пакетный менеджер слышали? Кто в здравом уме будет использовать ЭТО для обновления?

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

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

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

Где там имя типа. после двоеточия?

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

Чукча жопойпоклавиатурепрыгатель. Иногда результат компилируется.

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

Лень.

Иди в перл, там можно короче всего писать.

А еще больше лень запоминать, какие функции требуют слайс, а какие - строку

Ничего, сделают для Раста IDE, потерпи.

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

Ну и тут не пересекается. fn имя<Тип: Трейт>(параметр: Тип). Если путаете угловые скобки с круглыми, советую бросить (или не начинать) программировать.

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

Если предположить, что «метательная ссылка» - это указатель, то зачем так сложно? Неужели нельзя одним словом это обозначить? Без всяких коробок с селфями?

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

Обязательно брошу. Не моё это занятие - программировать.

Нормальное объявление подобной функции в любом другом языке можете увидеть.

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

Вообще, мутабельная, да. Коробки — ну а чо в си без маллока нельзя? Селф — это какая-то дичь конкретного кода, тебя никто не заставляет писать его, как и писать код вида boost::asio::ssl::stream<boost::asio::ip::tcp::socket> на плюсах.

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

Один хрен. Можно назвать «часто используемый указатель» (из 100500 разных вариантов). Вопрос - зачем так громоздко? Неужели нельзя одной конструкцией обойтись?

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

О да. Очень напоминает лучшие традиции плюсовой наркомании.

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

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

std::make_unique<TypeName>(new TypeName()); — видимо намного короче? В расте старались уйти от плюсов и сделать все максимально явно.

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

Другое дело, что Box используется так часто (и намного чаще, чем сырой указатель, доступный лишь в unsafe-коде), что следовало бы сделать символ *foo эквивалентом Box<foo>, а сырой указатель пусть будет Raw<foo>.

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

Что за Box

Владеющий указатель, аналог unique_ptr.

Что за Self?

Тип объекта, в методе которого выполняется код.

Что за враппинги-шмаппинги?

Облагороженная версия кодов возврата.

Это всё - какой-то набор фарша для компилятора.

Это обычный относительно низкоуровневый код.

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

std::make_unique<TypeName>(new TypeName()); — видимо намного короче?

Вы, полагаю, хотели написать std::unique_ptr<TypeName>(new TypeName()), поскольку make_unique будет выглядеть иначе: std::make_unique<TypeName>().

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

На плюсах этот код не так выглядит:

std::make_unique<TypeName>()

И нет никаких врапов-анврапов.

Максимально явно - это хорошо. Но хоть как-то должны частые операции быть проще. Вот gene1 ниже дело говорит.

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

std::make_unique<TypeName>(new TypeName());

std::make_unique<TypeName>(), вообще-то.

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

Сейчас уже не проканает из-за обратной совместимости.

Как вариант, добавить новый символ или комбинацию, например @foo или *&foo, но тогда еще больше будут ругать символьную плотность кода. :-)

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