Выпуск Rust 1.40.0: #[non_exhaustive], усовершенствования макросов и прочие улучшения

Автор оригинала: The Rust Release Team
  • Перевод

Команда Rust рада сообщить о выпуске новой версии, 1.40.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.


Если вы установили предыдущую версию Rust средствами rustup, то для обновления до версии 1.40.0 вам достаточно выполнить следующую команду:


$ rustup update stable

Если у вас ещё не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску на GitHub.


Что вошло в стабильную версию 1.40.0


Основными новшествами являются введение атрибута #[non_exhaustive], улучшения macros!() и #[attribute]. Наконец, миграционные предупреждения анализатора заимствований стали ошибками в Rust 2015. Смотрите подробности выпуска для дополнительной информации.


#[non_exhaustive] структуры, перечисления и варианты перечислений


Предположим, вы являетесь автором библиотеки alpha, которая содержит pub struct Foo. Вы хотели бы сделать поля структуры alpha::Foo публичными, но не уверены, придётся ли вам в будущих выпусках добавить больше полей в Foo. Возникает дилемма: либо вы делаете поля приватными с последующими неудобствами, либо вы рискуете поставить пользователей в зависимость от полей и потом нарушит их код при добавлении новых. В Rust 1.40.0 представлен способ решить проблему с помощью #[non_exhaustive].


Атрибут #[non_exhaustive] прикрепляется к структуре или варианту перечисления и препятствует полному сопоставлению полей, созданию упомянутой структуры или варианта вне крейта с их объявлением. Следующий пример демонстрирует ошибки в крейте beta, зависящего от alpha:


// alpha/lib.rs:

#[non_exhaustive]
struct Foo {
    pub a: bool,
}

enum Bar {
    #[non_exhaustive]
    Variant { b: u8 }
}

fn make_foo() -> Foo { ... }
fn make_bar() -> Bar { ... }

// beta/lib.rs:

let x = Foo { a: true }; //~ ОШИБКА
let Foo { a } = make_foo(); //~ ОШИБКА
let Foo { a, .. } = make_foo(); //~ OK
          // -- `beta` все еще будет компилироваться при добавлении полей.

let x = Bar::Variant { a: 42 }; //~ ОШИБКА
let Bar::Variant { b } = make_bar(); //~ ОШИБКА
let Bar::Variant { b, .. } = make_bar(); //~ OK
                   // -- `beta` все еще будет компилироваться...

Что же происходит за кулисами? Видимость конструкторов для #[non_exhaustive] структуры или варианта перечисления будет понижена до pub(crate), тем самым запрещая их использование в сторонних крейтах.


Возможно, что более важным аспектом #[non_exhaustive] является то, что атрибут может быть прикреплён к самим перечислениям. Вот код, взятый из std::cmp::Ordering:


#[non_exhaustive]
pub enum Ordering { Relaxed, Release, Acquire, AcqRel, SeqCst }

В данном случае #[non_exhaustive] гарантирует возможность добавления новых вариантов в будущем. Это достигается запретом другим пакетам к использованию исчерпывающего сопоставления с образом для Ordering. Компилятор бы отклонил следующее:


match ordering {
    Relaxed | Release | Acquire | AcqRel | SeqCst => { /* logic */ }
    //~^ ОШИБКА; если новый вариант был бы добавлен,
    // это сломалось бы, если ошибки не было бы с самого начала.
}

Вместо этого другие пакеты теперь должны учитывать возможность появления новых вариантов перечисления, например добавляя подстановочный знак _:


match ordering {
    Relaxed | Release | Acquire | AcqRel | SeqCst => { /* logic */ }
    _ => { /* logic */ } // OK; если будут добавлены новые варианты, ничего не сломается.
}

Подробная информация об атрибуте #[non_exhaustive] доступна в отчёте о стабилизации.


Улучшения макросов и атрибутов


В 1.40.0 мы внесли несколько улучшений в макросы и атрибуты, включая:



Миграционные предупреждения анализатора заимствований становятся ошибками в редакции Rust 2015


В выпуске 1.35.0 мы сообщили, что NLL появился в редакции Rust 2015 после первого выпуска для 2018 редакции в Rust 1.31.


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


Предыдущий выпуск Rust 1.39.0 заменил эти предупреждения на ошибки для кода с 2018 редакцией. Rust 1.40.0 применит те же самые изменения для кода 2015 редакции, навсегда закрывая эти дыры в безопасности. Вместе с этим компилятор даже почистили от старого кода!


Если ваш проект не собирается из-за вышеописанных изменений, или вы хотите узнать больше, читайте пост Niko Matsakis's.


Больше константных функций в стандартной библиотеке


Начиная с Rust 1.40.0, следующая функция помечена как константная (const fn):



Стабилизированные функции в стандартной библиотеке


В Rust 1.40.0 были стабилизированы следующие функции и макросы:



Другие изменения


Синтаксис, пакетный менеджер Cargo и анализатор Clippy также претерпели некоторые изменения.


Пожалуйста, прочтите заметки о совместимости, чтобы узнать, затронут ли вас эти изменения.


Участники 1.40.0


Множество людей собрались вместе, чтобы создать Rust 1.40.0. Мы не смогли бы сделать это без всех вас, спасибо!


От переводчиков


С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов.


Данную статью совместными усилиями перевели andreevlex, blandger, funkill, Hippolot, P0lunin, PsyHaSTe и LooMaclin.

Комментарии 58

    0

    Вообще non_exhaustive легко делается при помощи unit поля в структуре или варианта в енаме. Хотя в последнем случае это плохо тем что он виден.
    Видел я плач ярославны на реддите, что это якобы плохая фича.

      +4

      Ну мое мнение что фича действительно не очень. Раньше если мы получали при добавлении варианта ошибку компиляции, то теперь мы обязаны написать еще одну ветку в матче. Которая (вангую) в 99% будет либо паникой либо молчаливым проглатыванием варианта с возвратом какого-то дефолта.


      В некотором смысле фича абсолютно противоположена философии раста.

        +1

        Я тоже с этой фичей не сразу смирился, ещё в описании релиза приводят atomic::Ordering — да, мало какой "пользовательский" код будет этот enum матчить, но я плохо представляю какую логику можно воткнуть в _. Ну кроме паники, что несколько портит всю идею. Лучше бы про io::ErrorKind сказали.


        В общем, фича иногда полезная, но позволяет переносить проблемы из библиотеки в пользовательский код. Буду надеяться, что её будут использовать аккуратно.

      • НЛО прилетело и опубликовало эту надпись здесь
          +4
          Мне кажется что все равно в текущей модели, уровень когнитивных нагрузок совсем другой. Сейчас комфортно пользоваться всеми прелестями С++ можно только если ты уже программируешь лет 15-20 и научился обходить все подводные камни. Или же можно писать используя где-то 3-5% языка С++ (или даже регрессировать на С) и в принципе все будет более менее, особенно если ты делаешь что-то приземленное вроде numerical computing. Если нужен «кровавый enterprise» то конечно можно взять или C# или Kotlin, им Rust не конкурент и не пытается им быть.
          • НЛО прилетело и опубликовало эту надпись здесь
              +3

              Ну вы просто знаете C и имеете опыт программирования на нем, но не знаете Rust и не имеете опыта программирования на нем. Конечно, в таком случае для вас С предпочтительней. А вот для меня — наоборот ) Я программировал и на том, и на другом, и Раст для меня предпочтительнее, особенно если нужно что-то "быстрое и на коленке", как ни странно.

              +3

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

              • НЛО прилетело и опубликовало эту надпись здесь
                  0

                  Почему же сразу религиозный? Я вроде бы вполне рациональные доводы привел. Может быть вы недостаточно повидали «кровавого enterprise» и не в курсе, чем он болен и каково лекарство )

                  • НЛО прилетело и опубликовало эту надпись здесь
                      0

                      Лучшая типобезопасность — вот причина, почему Kotlin зашел. У Scala тоже был шанс, но она сама в себе запуталась, оказалась слишком сложной.

                      • НЛО прилетело и опубликовало эту надпись здесь
                  +1

                  Rust не претендует на место Java, т.к. приходится бизнес-логику мешать со всякими RefCell, Arc, Rc, Box, что крайне неудобно.

                    0

                    Ну и что? Почему вы решили, что это вообще составляет проблему? )


                    Я вот работал с несколькими крупными веб-приложениями, написанными на Rust, и в них Box и RefCell практически не использовались совсем (!), а там, где все-таки использовались — в единичных местах — никаких проблем и затруднений они не вызывали. Что же касается Arc и Mutex — так это вообще благо, ибо КОРРЕКТНЫЙ многопоточный код на Rust пишется в разы проще, чем на Java.


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

                    • НЛО прилетело и опубликовало эту надпись здесь
                        +1

                        Обычно структуры используются не сильно большие, чтобы их упаковывать, чаще всего они — Copy-типы. Ну а коллекции — в них упаковка скрыта от пользователя. RefCell же полезен в связке с Rc, а когда у вас шаренных объектов и так мало, то еще меньшему числу нужна шаренная мутабельность. )

                        0
                        Эмм… И что? Почему вы решили, что это вообще составляет проблему?

                        Потому что это привносит дополнительные неудобства! Концепцию лайфтаймов можно сборщиком мусора полностью убрать, что прикладные языки и делают, иначе приходится пользоваться умными указателями Arc и т.д. в некоторых случаях, которые не так уж и редко случаются. Например, создаёте вы N потоков в функции и передаёте им данные по ссылке, которыми владеет эта функция, а потом .join() в конце той же функции этих потоков, тогда придётся в Arc оборачиваеть/использовать scoped threads. В языке с GC такой проблемы бы не возникло вообще.


                        Что же касается Arc и Mutex — так это вообще благо, ибо КОРРЕКТНЫЙ многопоточный код на Rust пишется в разы проще, чем на Java.

                        Он пишется проще из-за правила "На один объект в один момент времени не могут указывать две изменяемые ссылки" и нормальной иерархической изменяемости, а Arc — это продление времени жизни объекта, что сборщик мусора сам по себе делает. Мьютекс бы забирал себе изменяемую ссылку, которая по определению GC живёт столько, сколько на неё указывают, и передавали бы просто Mutex<T>, а не Arc<Mutex<T>>. Концепция владения тоже, ИМХО, ненужна в языке для прикладных задач.


                        Я часто слышу, как люди, которые особого опыта-то и не имеют в enterprise, пытаются априори отгородить его от Rust. Зачем вы это делаете?

                        Я пишу ентерпрайз на Java, и в очень многих местах он объективно удобнее Rust. ИМХО, идеальный прикладной язык — это ООП язык с GC и возможностями формальной верификации программ системой типов как в Idris. Тогда было бы очень годно.

                          +2
                          это ООП язык с GC и возможностями формальной верификации программ системой типов как в Idris

                          Фигасе вы загнули ) Вряд ли возможна система типов "как в Idris", совместимая с ООП.


                          Ну, ваш взгляд имеет право на существование. Но я подозреваю, что вы либо мало работали с Rust и он вам просто непривычен, либо какой-то неправильный энтерпрайз у вас был на Java ) Без ада с NPE.


                          Концепция владения тоже, ИМХО, ненужна в языке для прикладных задач.

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


                          В языке с GC такой проблемы бы не возникло вообще.

                          В итоге там возникла бы другая проблема — гонка данных. Так что эта простота оказывает медвежью услугу: она создает видимость, что можно вот так просто взять и расшарить объект между потоками, не задумываясь о владении. Поэтому в той же Java многопоточное программирование — это совсем отдельное минное поле, требующее специальной подготовки джависта. А в Rust это вписывается очень органично — разок напрягся в самом начале, и дальше просто переиспользуешь уже имеющийся опыт )

                            0
                            Фигасе вы загнули ) Вряд ли возможна система типов "как в Idris", совместимая с ООП.

                            Смотря что под ООП понимать, и что под ФП. У всех ведь разные определения в голове на этот счёт)


                            Ну, ваш взгляд имеет право на существование. Но я подозреваю, что вы либо мало работали с Rust и он вам просто непривычен, либо какой-то неправильный энтерпрайз у вас был на Java ) Без ада с NPE.

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


                            В итоге там возникла бы другая проблема — гонка данных.

                            Я не вижу гонки данных в моём примере, ведь мы делим лишь неизменяемые данные между потоками. Если такое же правило применить, как и в Rust (две изменяемые ссылки в одно и то же время нельзя), то и гонок данных можно избежать.

                              0

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

                                0

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

                                  +1

                                  А как вы можете быть в этом уверены?


                                  Вот на .NET мы на одном унаследованном проекте добавили кеширование некоторых неизменяемых объектов для ускорения, после чего на проде выяснилось, что часть из них была на самом деле изменяемой...

                                    +1

                                    Потому что в C# неизменяемость кастрированная:


                                    using System;
                                    
                                    public class Test
                                    {
                                        class A {
                                            public int a;
                                        }
                                    
                                        class B {
                                            public readonly A obj = new A();
                                        }
                                    
                                        public static void Main()
                                        {
                                            B b = new B();
                                            b.obj.a = 34;
                                        }
                                    }

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

                                      +1

                                      Что-то я не увидел в ваших сообщениях выше языков с иерархической неизменяемостью… Надеюсь, это вы не про Java так сказали?

                                        +1
                                        Он пишется проще из-за правила "На один объект в один момент времени не могут указывать две изменяемые ссылки" и нормальной иерархической изменяемости...

                                        Конечно нет, я про Rust.

                                          +2

                                          Ну так я вам и объясняю почему на Rust многопоточный код писать проще.

                                +1
                                Смотря что под ООП понимать, и что под ФП. У всех ведь разные определения в голове на этот счёт)

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

                                  0
                                  Смотря что под ООП понимать, и что под ФП. У всех ведь разные определения в голове на этот счёт)

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

                                  Есть такие понимания, в которых не важно. Более того, оно не было важно в изначальной трактовке термина от Алана Кея(если уж занудствовать).
                                  (Поэтому я за то чтобы выкинуть термин ООП за неоднозначность и взять что-нибудь конкретное и не дискредетировавшее себя).
                                    0

                                    Я склоняюсь в определению "ООП это как в Java".


                                    А ООП по Кею в наши дни называется "акторная модель".

                                      –1
                                      Я склоняюсь в определению «ООП это как в Java».

                                      А что значит «как в Java»? В Java, много чего есть.

                                      Если про «3 Кита» — ну, ничего хорошего скрывающегося под этим определением я не видел. Мало этого что-бы внятную разницу иметь между процедурным програмированием и ООП.
                                      Без наследования, которое выше обсуждалось, жить точно можно и думаю лучше чем с ним, при удобной композиции, делегатах и т.п.

                                      Да и есть мысль что большая часть кода на Джаве(да и любом другом мейнстрим-языке) это, в силу старых привычек, легаси и старых стандартов, скорее процедурный код(с классами, да). Люди до сих пор делают сущности из геттеров/сеттеров, и выносят логику в сервисы.
                            0
                            в них Box и RefCell практически не использовались совсем (!), а там, где все-таки использовались — в единичных местах — никаких проблем и затруднений они не вызывали.

                            Только что из actix-web подсмотрел:

                              0

                              А какое имеют отношение потроха библиотеки к прикладному коду, который будет использовать ее? Приведите пример, где использование Payload потребует в клиентском коде заморачиваться с боксами и RefCell.

                                +1

                                Понимать этот код. Вот пример с Pin в моём пет-проекте: https://github.com/Hirrolot/finshir/blob/master/src/core/connection/mod.rs#L41 — сначала .get_mut() на пине, потом в ветках обратно заворачиваем в Pin, или pin-project можно использовать. К бизнес-логике отношения примерно никакого не имеет.

                      +4
                      Черт, смотрю я на Rust, он становится все сложнее и сложнее

                      Давайте посмотрим на этот выпуск — что поменялось? Переименовали unimplemented -> todo, ок. Добавили новый атрибут в стд — ок. Функционал который задперикейтили год назад и сыпали варнингами теперь окончательно выпилили — ок. Ну и пачку тривиальных функций добавили.


                      Вы видите в этом особое усложнение?


                      может дешевле работать на сырых указателях C++ (просто аккуратно) а для больших приложений взять какую-нибудь Scala?

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


                      А писать на плюсах аккуратно имхо невозможно, как из раза в раз доказывают всевозможные отчеты разных компаний.

                        0

                        Скала сильно переусложнена ИМХО, Раст там и рядом не стоял в аспекте "когнитивной нагрузки", которую зачастую требует скалистый код.

                          +1

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


                          Вторая проблема — неидиоматичность. Неидиоматичный раст написать тяжело потому что в половине случаев такой код просто не соберется, и придется спрашивать у сообщества как делать, в половине соберется, но придет клиппи и скажет как заменить. В скале же если не получается сделать правильно можно налепить что-то в стиле "Беттер джавы" и получить все те же проблемы, но только теперь со странным синтаксисом.




                          Насчет типов — раст намного лучше мейнстрим языков, но все же ощутимо уступает более продвинутым системам. Тот же многопоток который одна из киллер фич раста писать на STM на порядок проще и приятнее, чем обмазываться арками и мьютексами. Если можно себе позволить гц и вам не жалко 50-100% производительности и x2-x10 памяти, то можно брать языки с более сильными системами типов и гц.

                            +1
                            Скала сложнее только если смотреть на плотность информации на строчку кода. Если смотреть в абсолютных величинах, то она получается попроще.

                            Как хаскелист говорю, что скала переусложнена (и вообще в uncanny valley).


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

                              0
                              Как хаскелист говорю, что скала переусложнена (и вообще в uncanny valley).

                              1. Есть мнение, что в скале синтаксис попроще будет хаскелля. Если тупо сравнить количество синтаксических конструкций и сложность написания парсера
                              2. Скала интересна тем что это жвм, эрго 100 миллионов библиотек на любой вкус. На хаскелле — чуть в сторону от проторенной тропинки и всё.

                              Хотя мне лично ML синтаксис нравится больше. Но сейчас дотти ведь выходит, там и синтаксис подкрутили, и крутые штуки вроде частичных вычислений. В хаскелле такого нет.

                              • НЛО прилетело и опубликовало эту надпись здесь
                                  0

                                  В принципе хаскель для тех же задач что и жаба мне кажется — сервисы там всякие писать, в базки лезть. Ну, в общем обычная прикладная вещь.


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

                                  0
                                  Есть мнение, что в скале синтаксис попроще будет хаскелля.

                                  Лично у меня от этого бесконечного [_] рябит в глазах и начинает болеть голова.


                                  Если тупо сравнить количество синтаксических конструкций и сложность написания парсера

                                  Ну вот, например, описание всех возможных экспрешонов: http://hackage.haskell.org/package/template-haskell-2.15.0.0/docs/Language-Haskell-TH-Syntax.html#t:Exp, включая некоторые расширения. А как бы оно выглядело для скалы?


                                  Скала интересна тем что это жвм, эрго 100 миллионов библиотек на любой вкус.

                                  А как, кстати, ненативные и неидиоматичные для скалы библиотеки в ней ощущаются? Удобно ли с ними работать?


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

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

                                    0
                                    Лично у меня от этого бесконечного [_] рябит в глазах и начинает болеть голова.

                                    Ну, ML синтаксис вроде поприятнее выглядит, тут ничего не скажешь


                                    Ну вот, например, описание всех возможных экспрешонов: http://hackage.haskell.org/package/template-haskell-2.15.0.0/docs/Language-Haskell-TH-Syntax.html#t:Exp, включая некоторые расширения. А как бы оно выглядело для скалы?

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


                                    А как, кстати, ненативные и неидиоматичные для скалы библиотеки в ней ощущаются? Удобно ли с ними работать?

                                    Не очень, но удобнее чем писать их самому.


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

                                    Ну вот например:


                                    https://scastie.scala-lang.org/bR8NNUdQS5a2fen1T8LVFw


                                    На FPure были неплохие доклады про успехи на этом поприще, впрочем я думаю вы про проекции Футамуры и так в курсе. Ну и там же всякие штуки про автоматическую оптимизацию наивной функции let y = sqr(x, 5) в let xx = x*x; let y = xx*xx*x

                              0

                              Как вам такая когнитивная нагрузка?



                              И нет, в скале даже близко так сложно бы не вышло.

                              • НЛО прилетело и опубликовало эту надпись здесь
                                  0

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


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




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

                                    0

                                    Так ведь спор пока и идет насчет ширины этого отверстия.

                                      0

                                      Цепляться к неточностям аналогии — плохой способ вести диалог.


                                      Я уверяю, что если у меня не будет ограничений на производительность (скажем, меня устроит производительность уровня Java), то на Scala/Haskell я напишу более безопасное и масштабируемое решение, и за меньший срок.

                                  0

                                  Когда сообщения об ошибках разрывают поток кода — совершенно невозможно ничего понять (тому кто видит этот код впервые). Так что да, в таком оформлении — нагрузка высока. Но лично я так не программирую на Rust.

                              +4
                              Я люблю Rust, но его zero cost совсем небесплатен для мозга программиста…

                              ИМХО, "просто аккуратно" пользоваться C++ — вещь ещё более "небесплатная".

                                +1

                                Эмм… Я вот программирую на Расте каждый день и уже устаю ждать некоторых фич, которые очень хочется иметь в языке и которые все пилятся и пилятся. Где вы увидели усложнение языка? Кроме async/await в последнее время вообще небыло никаких принципиальных нововведений.

                                  +1

                                  Pin

                                    0

                                    Узкая ниша для неперемещаемых в рантайме данных.

                                      0

                                      Любой асинк код — это не узкая ниша.

                                        0

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

                                          0

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

                                  0

                                  Дык, все живые языки развиваются. Даже в го, киллер фичей которого считаю простоту освоения, дженерики завезти хотят.


                                  И с другой стороны: столько нужных фич в расте ещё не сделаны! (:

                                  • НЛО прилетело и опубликовало эту надпись здесь

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

                                Самое читаемое