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

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

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

Да. Но это не проблема языка. Он просто молодой ещё.

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

Если у вас горит от print, то тут уже ничем не поможешь.

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

fn? Зачем? Что, компилятор настолько тупой, что ему понадобились эти два символа? Без этого никак? Мало того что совершенно бесмысленное сокращение слов ради невнятной экономии, так ещё и не шибко нужные дополнительные ключевые слова.

А ты много языков программирования написал, чтобы судить грамматику? Например есть такие вещи, как двусмысленные грамматики. Что такое a < b > c в C++? Булевое выражение ((a < b) > c) или объявление переменной с, типа a<b>? Непонятно, потому что грамматика неоднозначная. И таких моментов много. Скорее всего без fn возникали бы неоднозначности, без которых лучше обойтись.

Зачем две точки в параметрах? Вот какую практическую цель они несут?

Разделять тип и название переменной.

Почему другие языки без них обходятся?

Ты паскаль вообще видел? Нормальные языки все так пишутся.

Зачем добавлять ненужные сущности?

Пиши на машинном коде, вот уж где нет ненужных сущностей, всё по делу.

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

Нет, это твои суждения — говно. Но хорошо, что написал, сразу стало понятно, что критика твоя яйца выеденного не стоит.

Зачем bool там вообще писать? Во первых по телу функции компилятор и так может определить возвращаемый тип, а во вторых зачем тогда fn. Либо указывать тип, либо fn. Вместе они нафиг не нужны.

Сигнатуру функции всегда нужно писать. Даже в хаскеле, который выведет все типы, считается хорошим тоном всегда писать полные сигнатуры. Как минимум это предотвращает ошибки вроде нечаянного return-а неправильного типа.

println - кто блин кого, что и куда печатает? В 2017-м году? Серьезно?

Ты вообще программы писал? Про отладочную печать слышал?

Дань чему это бесмысленная «печать» не пойми чего и куда? У меня перед глазами сразу матричный принтер возникает. Никакой связи с консолью. Я бы руки отрубил создателям за столь дебильное наименование функций.

Ага, а на write ты будешь ругаться, мол никакой связи с шариковой ручкой. Это называется — к чему бы прикопаться?

Legioner ★★★★★
()

Интересный проект. Хотя бы по количеству споров вокруг него.

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

Эпоху неограниченной оперативной памяти? Да. Эпоху неограниченных L2/L3-кешей? Увы, нет!

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

…но синтаксис действительно местами коряв. Хотелось бы видеть что-нибудь вроде:

let is_divisible_by (lhs, rhs u32) bool {
    return (lhs % rhs) == 0;
}
или даже:
let is_divisible_by (lhs, rhs u32) return (lhs % rhs) == 0;
(return оставил для ясности, можно и без него).

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

Это может быть и в функциональном стиле, что-то типа: using std:console; console_write(«hello world»);

Ты без бюрократии с using'ами жизнь не представляешь?

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

Разделять тип и название переменной.

А разве в сигнатуре функции можно объявить несколько переменных не указывая тип каждой? Я не одного языка не видел с таким поведением. А значит хватило бы пробела.

Ты паскаль вообще видел? Нормальные языки все так пишутся.

Паскаль и нормальный? О_О

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

В golang можно в сигнатуре функций опускать одинаковые типы

func(x, y int) int

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

А разве в сигнатуре функции можно объявить несколько переменных не указывая тип каждой? Я не одного языка не видел с таким поведением. А значит хватило бы пробела.

Не понял. Теоретически может и можно. Если ты меня спросишь — я проголосую за двоеточие. Потому что с ним проще читается код. Ты же в тексте пишешь знаки препинания, хотя и без них в 99% всё понятно.

Паскаль и нормальный? О_О

Паскаль просто шикарный ЯП и Delphi это показала, жаль, что потом все полимеры профукали. Но по читабельности паскаль на голову выше сишных макарон. По скорости компиляции, кстати, ему вообще равных не было, хотя не уверен, с чем именно это было связано.

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

Напиши свой вариант как должна выглядеть эта функция

Да вариантов много, просто убрать лишние сущности. Даже у typescript'a всё не так печально. В том же C++ или C# нет особых проблем с записью функций. Базовый синтаксис вменяемый. Я бы сказал задача нового языка довести C++ like язык по удобству эксплуатации до C# и добавить пару плюшек, например множественные возвращаемые значения без использования structure и tuple. Но зачем добавлять новые слова типа function, я просто не вижу смысла.


Если у вас горит от print, то тут уже ничем не поможешь.

Ну почему, поможешь. Просто не нужно расхлябанности, мутных реализаций, не несущих ничего добавлений и усложнений синтаксиса в таких вещах как языки программирования. Четкость, простота и всё будет хорошо. Может в третьей редакции ребята исправятся.


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

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

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

let ужо используется для переменных. Будешь путаться при быстром чтении

С двоеточиями в скобках мне понятней, чем без них, по той же причине. А с лайфтаймами вообще каша выйдет без разделителей

=> не нравится. Я бы предпочел двоеточие. Но это вкусовщина и не принципиально

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

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

Ну например:

Due to the struct field optimisation, using transmute on
structs that have no repr attribute or #[repr(Rust)] will no
longer work. This has always been undefined behavior, but is
now more likely to break in practice.

Падажжии!

This has always been undefined behavior, but is
now more likely to break in practice.

И эти люди ~запрещают мне ковыряться в носу~ рассказывают про undefined behavior в других языках!

shkolnick-kun ★★★★★
()
Ответ на: комментарий от d9d9

В том же C++ нет особых проблем с записью функций.

Wut?! Там всё ещё хуже.

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

Не понял.

Тут привели пример того что я имел ввиду Rust 1.18 (комментарий) Паскаль просто шикарный ЯП В большинстве языков я могу объявить переменную и сразу же присвоить ей значение. В паскале надо лезть куда-то вверх, объявив переменную, и только потом возвращаться в код ниже, где её можно использовать. Очень удобно же(сарказм)

Ты же в тексте пишешь знаки препинания, хотя и без них в 99% всё понятно.

Что не понятного в такой записи

int a
Знаки препинания нужны так как без них всё сольётся в огроменный ком. Для коротких предложений, записанных по одному в строке можно жить и без них.

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

Так этоже unsafe код, там и еще и не такое бывает.

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

Паскаль и нормальный? О_О

Ну если норма == большинство, то, конечно, си-подобный синтаксис вне конкуренции.

А вот с точки зрения логики, удобства и однозначности паскалевский синтаксис безусловно лучше сишного.

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

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

В основном сторонники «чёткости, простоты, модульности» делают всё так, что код разбухает в раз десять в некоторых случаях, при том что пользоваться этим будут чуть чаще чем никогда.

NextGenenration ★★
()

Среди обычных программистов наконец-то стали использоваться линейные типы. Может когда-то в моду войдут и зависимые типы. И еще более крутые вещи. Развитие системы типизации в языках программирования это путь в будущее и в прогресс. Только слишком медленно всё это приходит в массы.

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

А вот с точки зрения логики, удобства и однозначности паскалевский синтаксис безусловно лучше сишного.

Я не защитник сишного. Я противник бюрократии и возможностей прострелить ногу. Зачем нужно отделять объявление переменной от инициализации?

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

В том же C++ или C# нет особых проблем с записью функций.

Как раз в С++98 при использовании шаблонов было достаточно проблем для того, чтобы в C++11 сделали специальный синтаксис вида:

auto foo(args types) -> return_type {...}

Другое дело, что в Rust-е ключевое слово fn выбрали потому, что одному из разработчиков не нравилось набирать function в JavaScript-е.

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

Да чего толсто-то. Есть комбинаторное программирование, например. И оно весьма удобно. Я всё-таки за то, чтобы указывать тип, а переменные указывать и не нужно, как и сами переменные не очень и нужны.

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

А вообще ты на какой стороне, считаешь ли ты что если баг попал в релиз то фиксить его нельзя, потому что это может нарушить совместимость?

Как например разработчики LLVM, у них текущий стабильный релиз 4.0.1 иногда генерирует некорректный код для ARM, на что разработчики отвечают что бакпортить фиксы в релиз не будут, потому что это «может» добавить новые баги.

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

Есть комбинаторное программирование, например.

Есть и однострочники на перле, только вот не всегда их возможностей хватает

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

Проблемы отсутствия формальной верификации.

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

Или без скобок, т.к. Rust не тупой и сам понимает приоритет

fn is_divisible_by (lhs: u32, rhs: u32) -> bool {lhs % rhs == 0}

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

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

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

И каких же возможностей не хватает?

Покажешь что-то типа парсера, работы с деревьями, гуи?

Если у кого-то не слишком гибкое мышление, то это не означает проблемы технологии.

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

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

fn? Зачем?

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

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

что-то типа парсера

https://github.com/Geal/nom кажется эта библиотека весьма много использует комбинаторную логику и композицию.

работа с деревьями

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

гуи

Реактивное программирование прекрасно решает эту задачу.

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

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

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

fn? Зачем?

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

Зачем этот -> перед bool? От этого стало понятнее, что параметры закончились?

Именно.

Сравни fn d9d9(fun: fn (i32, i32) -> i32) -> fn (i32) -> i32 и d9d9 (fun (i32, i32) i32) (i32) i32. Если ты считаешь, что второй вариант - читабельней, то тебе нужно провериться на лиспофажество.

по телу функции компилятор и так может определить возвращаемый тип

Видел сообщения об ошибках в Цацкеле? Хочешь так же? Я - нет.

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

println! - это не часть языка, это макрос из стандартной библиотеки.

Никаких глобальных невнятных функций.

Для макросов ещё не запилили пространства имён, было не в приоритете. Когда запилят, просто засунут его куда-нибудь в std::fmt и сделают импорт в prelude.

В том же C++
нет особых проблем с записью функций
базовый синтаксис вменяемый

Серьёзно?!

int32_t (*d9d9(int32_t fun(int32_t, int32_t)))(int32_t)

Вот это ты считаешь вменяемым?

Может в третьей редакции ребята исправятся.

Конечно. Послушают великого тебя и исправятся.

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

fn нужен, т.к. есть и другие конструкции, например trait или impl и хорошо что эти служебные слова стоят на первом месте, т.к. код хорошо читаемый.

trait A { }

impl B for A { }

fn C() { }

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

Сравни fn d9d9(fun: fn (i32, i32) -> i32) -> fn (i32) -> i32 и d9d9 (fun (i32, i32) i32) (i32) i32. Если ты считаешь, что второй вариант - читабельней, то тебе нужно провериться на лиспофажество.

Это функция высшего порядка?

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

нужно провериться на лиспофажество

Вот это ты считаешь вменяемым?

2017 год, у всех давно цветные мониторы и подсветка синтаксиса. И да, каждый человек по разному парсит выражения в скобочках.

BceM_IIpuBeT ★★☆☆☆
()

Когда будет Rust 2.0? Что в нем обещают? Изменения будут совсем уже ломающие?

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

https://github.com/Geal/nom кажется эта библиотека весьма много использует комбинаторную логику и композицию.

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

Комбинато́рное программи́рование (англ. function-level programming) — парадигма программирования, использующая принципы комбинáторной логики, то есть не требующая явного упоминания аргументов определяемой функции

Смотрю на код fn take4(i:&[u8]) -> IResult<&[u8], &[u8]>{

Реактивное программирование прекрасно решает эту задачу.

А что, в реактивном программировании не возникает задачи синхронизации потоков?

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

Если ты считаешь, что второй вариант - читабельней, то тебе нужно провериться на лиспофажество.

Ты говоришь так, как будто это что-то плохое.

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