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

Потому что это языки с GC. Ваш Кэп.

Блин, ну возьмите древнюю Ada, Object Pascal/Delphi, современный Swift. Языки без GC.

Ок, предложи твой синтаксис для этой строчки

Это ничего не изменит.

Не понятно другое: почему, когда кто-то говорит, что ему не нравится в Rust-е и что ему мешает в Rust-е, так сразу же Rust-оманы как с цепи срываются? Мое личное недовольство как-то подрывает популярность Rust-а или подрывает вашу личную веру в то, что вы сделали правильный выбор?

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

Не понятно другое

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

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

Swift. Языки без GC

там ARC гвоздями прибит, и Swift - не системный язык, если тебе нужен перфоманс на iOs/OSX ты пишешь на плюсах или си, такие дела да

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

В Swift есть GC. Своеобразный, но GC. Заботится о памяти там не нужно.

В паскале вообще глобальные переменные и нет указателей и ссылок (насколько я помню).

почему, когда кто-то говорит, что ему не нравится в Rust-е и что ему мешает в Rust-е, так сразу же Rust-оманы как с цепи срываются?

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

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

В паскале вообще глобальные переменные и нет указателей и ссылок (насколько я помню).

Вы бы это, поосторожнее с демонстрацией своих познаний вне мира Rust-а. А то у вас то исключения из конструкторов в C++ оставляют объект наполовину инициализированным, то указателей в Pascal нет.

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

Я последний раз на паскале в универе писал. Могу ошибаться, о чём и упомянул.

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

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

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

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

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

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

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

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

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

upcFrost ★★★★★
()
Ответ на: комментарий от 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 ★★★★
()
Ответ на: комментарий от AntonyRF
public function backup(&mutable self, path: &mutable String) -> Result<()> {
pub fn backup(&mut self, path: &mut String) -> Result<()> {

Очевидно, что второй вариант легче читается

Вовсе не очевидно. Мне, например, первый вариант прочитать легче, чем второй.

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

Меня напрягает другое - сигнатура &mut String а не mut &String, ведь индикатор среза относится к типу, а не к переменной. В версии без mut так и пишется слитно, &String.

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

Это да, паскалевский (алголовский) синтаксис намного читабельнее сишного.

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

Емнип в ruby несколько похожий синтаксис.

Я уже здесь показывал синтаксис лямбд из Ruby. Он лучше Rust-ового тем, что рам есть либо открывающая do, либо открывающая {.

В Rust-е же когда сталкиваешься с || -> Result<()>, то слегка офигеваешь. Равно как и вот в таких случаях:

rayon::join(|| qsort(less),
   || qsort(greater));
Как-то не сразу приходит понимание, что здесь две(!) лямбды без параметров. В каком-нибудь другом синтаксисе это было бы для меня более очевидно:
rayon.join(() => qsort(less), () => qsort(greater))
или
Rayon::join lambda {qsort(less)}, lambda {qsort(greater)}

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

Он лучше Rust-ового тем, что рам есть либо открывающая do, либо открывающая {.

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

Как-то не сразу приходит понимание, что здесь две(!) лямбды без параметров

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

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

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

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

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

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

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

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

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

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

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

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

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

Так это сознательное решение было.

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