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)
Ответ на: комментарий от anonymous

Информативно. Давно о таком мечтал. Предлагаю не ограничиваться полумерами, а вернуться к программированию напрямую в машинных кодах.

Это было сделано, чтобы сократить запись.

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

Напиши небольшой пример на C#, а люди подскажут как это делается в Rust.

using System;

namespace Test {
  class Base {
    public virtual void Test() {
      Console.WriteLine("a");
    }
  }
  
  class Derived : Base {
    public override void Test() {
      Console.WriteLine("b");
    }
  }
  
  class Programm {
    public static void Main(string[] args) {
      Base t = new Derived();
      t.Test(); // напечатает b
    }
  }
}
NextGenenration ★★
()
Ответ на: комментарий от baist

У меня вопрос, почему ты решил взять эту библиотеку для x11 написанную вручную? Можно ведь сгенерировать более качественные биндинги при помощи bindgen. Попробую переписать твой пример ради эксперимента.

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

Как может существовать ооп без наследования?

Например, Алан Кей, считает С++ не совсем языком с ООП.

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

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

function GetCons(InputObj: TObject): ....
...
  if InputObj is TColdCounter then
    (InputObj as TColdCounter).GetConsumption
  else if InputObj is THotCounter then
    (InputObj as THotCounter).GetConsumption
...
, что даст нам портянку кода. Если бы была возможность для этой задачи использовать типаж, то мы бы знали что есть метод и нам не важен был бы класс объекта. Соответственно, кода пришлось бы писать меньше. И если в первом варианте мы можем попасть на exception т.к. можем всунуть не тот класс объекта, то в другом варианте компилятор не даст сбилдить при несоответствие типажи в входных параметрах.

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

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

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

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

Бред

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

Понял. В данном случае нужен интерфейс счётчика. Тогда у классов унаследованных от данного интерфейса можно будет дёргать метод без проблем. Правда

Но объекты имеют по историческим причинам разные классы родителей.

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

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

У каждого объекта-счётчика есть метод который возвращает текущий расход. Но объекты имеют по историческим причинам разные классы родителей. В итоге нам придётся указать TObject и сравнивать получаемые объекты с поддерживаемыми и получать доступ к методу по средствам, типа

А что, в ваших Дельфях интерфейсов нет в принципе?

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

Например, Алан Кей

Это тот самый заварной чайник, который сводит весь смысл ООП к пересылке сообщений между объектами?

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

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

А что, в ваших Дельфях интерфейсов нет в принципе?

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

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

Это тот самый заварной чайник, который сводит весь смысл ООП к пересылке сообщений между объектами?

Да тот чудак =)

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

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

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

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

Блин, так с чего тогда такие причитания: «Если бы была возможность для этой задачи использовать типаж, то мы бы знали что есть метод и нам не важен был бы класс объекта.»

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

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

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

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

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

Напиши «бред» ещё раз пять. Растокод от этого не перестанет быть перегруженным сложночитаемым говнокодом.

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

Мне виднее, я с этим кодом и небольшой группой программистов уже 3 года работаю. Я гарантирую, что наличие типажей в Delphi/FPC упростило бы жизнь в миллионы раз.

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

Хотя, Вы правы. Ни кто и на это бы не дал время =(

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

В таком случае, странно на него ссылаться-то. Мы вроде про ООП говорим, а Алан Кей тут каким боком? То, что он свой смолтолк считает идеалом ООП - ну так мало ли кто чем болен.

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

а во-вторых это всё равно через одно место.

Почему?

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

Это не моя база кода. Я форкнул и успел сделать 3 коммита. Мне нужен был MIT-SHM для иксов, а это в свою очередь нужно для движка. Для рисования на плоскости из пикселей без OGL и прочего. Я для плюсов под пингвина искал аналог виндового DirectDraw. Ну чтоб пиксели и больше нечего. В итоге остановился на XShmPutImage. А этот тянет за собой разделяемую память posix.

Добавил в проект быстренько дюжину функций и пару структур - готово к использованию. Я не стал заморачиваться. Про bindgen слышу в первый раз. Что сильная вещь?!

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

Так я и не читаю. Мне интересно, почему его так агрессивно защищают, говоря, что он легко читается. Вдруг я какую-то тайную фишку упустил.

Нет, оказалось все в норме. Как я и думал, очередная горстка фриков жрёт очередной кактус. Сожрёт - возьмётся за новый, как это было не раз.

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

Как всегда всё упирается в определение ООП.
И там правильно сказано «ООП которое совсем не такое как в С++»
Т.к. абстракция,инкапсуляция, наследование и полиморфизм есть.
Правда последние два только для трейтов.

А ты хочешь как С++, а это не C++.

Поэтому я и говорю, что бессмысленный срачЪ.

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

rust это ооп или нет?

В привычном и устоявшемся понимании — нет. Можно долго разводить демагогию про Кеевский ООП, про то, что он разный и вообще в C++ не правильный ООП, но простой ответ: нет, Rust это не ООП язык.

mersinvald ★★★★★
()
Ответ на: комментарий от NextGenenration
trait SillyPrinter {
    fn foo(&self) {
        println!("a");
    }
}

impl SillyPrinter for u32 {}

struct Derived(u32);

impl SillyPrinter for Derived {
    fn foo(&self) {
        // don't call a base. We don't need it
        // self.0.foo();
        println!("b");
    }
}

fn main() {
    let t: Box<SillyPrinter> = Box::new(Derived(0));
    t.foo();
}
red75prim ★★★
()
Ответ на: комментарий от AntonyRF

Типажи в расте как бы и есть интерфейсы как в решетке, но только наоборот. В решетке мы делаем интерфейс, а потом класс. В расте наборот - если же есть класс, то к нему можно присобачить интерфейс. При этом сам класс об этом не знает. Можно добавлять методы класса не используя наследования.

И это не ломает логики даже для примитивных встроенных типом. Можно добавить методы для целого 32-битного.

Именно поэтому наследование выглядить как impl A for B.

Причем вкусность в этом случае заключается в том, что если мы не подключили модуль с типажами, то и работать оно не будет. Если у нас два одинаковых типажа но с разными реализациями, нам не надо делать дважды наследование, или переписывать код. Достаточно подключить модуль и типаж автоматически подхватится. Собственно наследование не нужно.

Но это все тоже ООП с методами, с внтренним состоянимем и инкапсуляцией объектов.

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

В таком случае, странно на него ссылаться-то. Мы вроде про ООП говорим, а Алан Кей тут каким боком? То, что он свой смолтолк считает идеалом ООП - ну так мало ли кто чем болен.

Это к теме того, что есть разные формулировки ООП и под некоторые Rust попадает.

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

инкапсуляцией объектов

Ну справедливости ради, это не совсем так. В Rust единица инкапсуляции — модуль, а не структура/трейт.

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

Так я и не читаю. Мне интересно, почему его так агрессивно защищают, говоря, что он легко читается. Вдруг я какую-то тайную фишку упустил.

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

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

А вот ядро вполне себе может быть не проверено

Когда мы или кто-то другой будет писать новый софт, он заузает наш ЯП и все будет «зашибись». С уже написанным софтом «зашибись» не будет никогда, потому что даже если взять и исправить все проблемы, к нему будет более применим термин «переписанный софт», что по сути ~= «новый софт».

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

С уже написанным софтом «зашибись» не будет никогда

То есть не смотря на то что всё равно какие файлы с плюсами проверять старые не проверить?

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

А как же ключевое слово pub и его отсутствие? Разве оно не обрамляет собой объект?

Ваши споры нелогичны тем, что для вас ООП это обязательно некий стандарт программирования или поддержка d zpsrt синтаксическим сахаром. Но ведь это все подходы. На C тоже можно в ООП. Есть даже некая экзотика как GObject от Glib. Просто подход. В решетке есть свойства, но это не значит что так нельзя сделать на плюсах. Некоторые JS макаки считают что их язык функциональный. Видимо они не видели хацкеля.

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

Вы не поверите, но это в большинстве языков так.

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

Которое я никому не навязываю.

Чел, ты тролль. И ты именно навязываешь. Потому что не способен ответить на один простой вопрос: Тебе-то что до этого?

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

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

Когда-то мейнстримом было пренебрежительно относиться к JavaScript. А уж прототипный ООП никак не назовёшь простым и легко осваиваемым. И? Это кого-то остановило?

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

Так что ты просто тролль, который хочет срач.

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

С++ устарели, на сколько Rust подойдёт для его смены узнаем через года. Может кто-то запилит более мощный язык или более простой - хз. Но программист на С++ КМК частично занимается баданием с С++ вместо полезных действий. А многие вещи в С++ уж действительно выглядят как костыли, например, сколько сейчас типов указателей и строк в С++?

В общем, я рассчитываю на то, что появиться замена C++ и многие думают тут об этом же, и КМК Rust имеет шансы на это.

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

Мне нужен доступ к полю test. чяднт?

trait SillyPrinter {
    fn foo(&self) {
        println!("a");
    }
}

impl SillyPrinter for u32 {}

struct Derived {
    test : u32,
}

impl SillyPrinter for Derived {
    fn foo(&self) {
        // don't call a base. We don't need it
        // self.0.foo();
        println!("b");
    }
}

fn main() {
    let t: Box<SillyPrinter> = Box::new(Derived { test: 0 });
    println!("{}", t.test);
}

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

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

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

Если в родительском классе не определено поле test, то как ты к нему получишь доступ?

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

В случае с c# тебе надают по рукам за прямой доступ к полю

Кто? Можно же и к свойству применить.

В случае необхоимости я могу привести к базовому классу?

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

А как же ключевое слово pub и его отсутствие? Разве оно не обрамляет собой объект?

Можно заметить, что внутри модуля pub — всё. То есть модификаторы играют роль только при импорте модуля и использовании его внутренностей.

Ваши споры нелогичны тем, что для вас ООП...

Я же сказал, можно долго разводить демагогию, но для большинства ООП — это классическая троица из Java.
И когда задают такие вопросы — подразумевают именно эту интерпретацию термина, что даже по этому треду явно видно.
Можно сколько угодно заливать про то что у нас тоже ООП, но он другой, и я с этим согласен, в принципе, но новичков это только запутает и вызовет ощущение того, что где-то их на**ли.
Чести языку и сообществу это не делает

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

Я же сказал, можно долго разводить демагогию, но для большинства ООП — это классическая троица из Java.
И когда задают такие вопросы — подразумевают именно эту интерпретацию термина, что даже по этому треду явно видно.
Можно сколько угодно заливать про то что у нас тоже ООП, но он другой, и я с этим согласен, в принципе, но новичков это только запутает и вызовет ощущение того, что где-то их на**ли.
Чести языку и сообществу это не делает

Два чая.

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

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

А так я здесь, в отличии от вас, не страдаю. Я жую попкорн и наблюдаю за вашим срачем. Изредка позволяя себе реплики из зала. :)

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