Как стать автором
Обновить

Rust 1.86.0: преобразование в родительский трейт, поддержка изменяемой индексации для HashMap и срезов

Уровень сложностиПростой
Время на прочтение5 мин
Количество просмотров1.9K
Всего голосов 13: ↑13 и ↓0+16
Комментарии24

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

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

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

Ключевое слово - каждому. Это ошибочное целеполагание позволяет сделать оценку: 100 релизов по 6 недель == 12 лет.

Если у вас ещё не установлен rustup, вы можете установить его с соответствующей страницы нашего веб-сайта

Заинтересовался смыслом «нашего», вдруг переводчики больше чем просто переводчики. Нет, не больше, и по инерции попал на список поддерживаемых платформ, где неожиданно заметил и удивился

At this time, all Tier 1 targets are Tier 1 with Host Tools.

И действительно, iOS, WebAssembly и Андроид - Tier 2. Язык воспринимался бы лучше если бы это была Tier 1. Тем более что по жизни так оно и есть.

Поэтому приведённая выше оценка - оценка сверху.

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

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

Неправильно, у Rust есть понятие edition. Пишете код под какой-то желаемый вами edition и все. Потом язык развивается, выходят более новые версии, новый edition - а ваш код продолжает работать с новым компилятором, как работал со старым (в том числе - совместно работать с кодом, написанным под другими editions)

И это тоже не вполне правильно в части

ваш код продолжает работать с новым компилятором, как работал со старым (в том числе - совместно работать с кодом, написанным под другими editions)

Продолжает работать скомпилированный код, в терминах Rust это crate, а код исходный работать не будет. Доки приводят тривиальный пример - в достаточно старом коде могут быть переменные await и async.

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

Ничего подобного. Crate - это исходный код. Про то, что может ломаться скомпилитрованный - вообще говорить не стоит, т.к. статическая линковка, мы говорим именно про компиляцию. В старом коде, в котором есть await и async переменные, будет указано edition = "2015" в файле Cargo.toml, и его всё ещё корректно соберёт любой самый новый компилятор. И в качестве зависимостей эти крейты можно будет подключать в новые проекты, компилятор достаточно умён, чтобы собирать каждый крейт с учётом его edition.

Я еще только изщучаю Rust, у меня вот после обновления компилятора такое выдало. Это разработчик библиотеки что-то неверно в пакете указал или стандартная ситуация?
error: older versions of the wasm-bindgen crate are incompatible with current versions of Rust; please update to wasm-bindgen v0.2.88

Это является следствием исправления бага в компиляторе.

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

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

Все будет работать. Новый компилятор Rust скомпилирует код для старого edition по правилам старого edition. Это вообще не что-то удивительное - один и тот же компилятор c++ в режиме C++17 воспримет токен consteval совершенно не так же, как в режиме C++20. Код, написанный под C++17 продолжит компилироваться после апгрейда компилятора, пока используется режим C++17. Код, написанный под Rust 2021, продолжит работать после апгрейда компилятора, пока используется этот edition. Разница в том, что в C++, вообще говоря, нельзя смешивать код разных версий (да и тяжело это сделать в условиях текстового включения заголовков - попробуй-ка напиши header-only библиотеку не под ту версию, под которой компилируется потребитель), а в Rust можно. Поэтому в Rust не приходится думать о том, как максимально упростить переезд на новую версию (в отличие от C++, где из-за этого вылезают вещи типа std::copyable_function...)

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

А теперь спросите себя - почему edition указывается на уровне крейта а не на уровне файла?

Потом, обязаьельно потом, попытайтесь определить что такое конкретно "локальные правила комптляции".

Тогда станет понятно - в Rust старый компилятор поставляется вместе с новым, а создаваемые ими крейты - совместимы.

БОНУС: а совместимы они могут быть потому, что сборщика мусора нету.

А теперь спросите себя - почему edition указывается на уровне крейта а не на уровне файла?

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

Тогда станет понятно - в Rust старый компилятор поставляется вместе с новым, а создаваемые ими крейты - совместимы.

Компилятор тот же, просто новые фичи в старых edition превращаются в ошибки. Это не два компилятора - пайплайн на любую редакцию один единственный - лексер, парсер, AST, чекер и далее по списку.

а совместимы они могут быть потому, что сборщика мусора нету.

Это примерно никак не влияет на совместимость кода. Lua и Java, например, имеют сборщик мусора и вполне себе имеют совместимость - они оба превращаются в байткод и главное чтобы виртуальная машина поддеживала необходимый набор инструкций. У D/swift/Go похожая история. А у zig так и вовсе в одной кодовой базе куча разных аллокаторов может спокойно сосуществовать абсолютно не мешая друг другу и совместимости? если конечно интерфейс кому-нибудь не отломили, что маловероятно.

Неправильно, у Rust есть понятие edition. Пишете код под какой-то желаемый вами edition и все...

Ну так у С++ тоже есть стандарты, которые также можно выбрать при компиляции. Но это не отменяет изначального вопроса "сколько времени потребуется создателям Rust, чтобы постепенными улучшениями превратить его в монстра, похожего на С++?"

Потому что при любом развитии языка, он либо пытается сохранить совместимость со старой лексикой и начинает раздуваться (как С++), либо нарушается обратная совместимость лексики, но чтобы каждый раз не переписывать килотонны кода, вводятся ревизии, стандарты или edition. По сути, это новые варианты языка, но и старые нужно помнить и поддерживать.

Это точно такое же раздувание, только в другом ракурсе.

Но товарищ! Это же очень сильно другой ракурс. Одно дело - раздувается компилятор. Это где-то там кого-то там проблема. Другое дело - раздувается язык. Это не где-то там, а прямо тут прямо моя проблема.

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

Эта проблема свойственна любому не мертвому языку. На той же Java в энтерпрайзе запросто можно найти 8-ю версию, хотя уже 21-я давно вышла.

Синтаксис Java развивается так же как и С++ - расширяя существующий синтаксис не нарушая обратную совместимость и без необходимости привязываться к номеру версии.

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

Одно дело - раздувается компилятор. Это где-то там кого-то там проблема.

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

std::auto_ptr, std::*_fun, std::bind1st/2nd, std::unary/binary_function, codecvt/wstring_convert, std::iterator и тд. Не надо мне тут рассказывать про "просто указать -std новее". Мне доводилось последовательно переводить проект с изначального C++11 на 14, 17 и 20 (в течение 10 лет его жизни, со сменой целевых платформ и соответственно компиляторов) - емнип переход на 14 прошел "просто указать", а вот и 17 и 20 итерации потребовали ощутимых телодвижений, включая обновления библиотек Poco и Boost. Перевод кода, написанного в лучшем стиле C++98 на C++11 (до состояния без предупреждений компилятора) - это вообще задача сродни глубокому рефакторингу.

Перевод кода, написанного в лучшем стиле C++98 на C++11 (до состояния без предупреждений компилятора) - это вообще задача сродни глубокому рефакторингу.

Неоднократно приходилось заниматься подобными вещами, в том числе в некоторых опенсорсных проектах типа того же fheroes2 (который писался старой командой еще в нулевые - до C++11, разумеется). Да, какие-то предупреждения компилятора бывали, особенно если до меня они были включены по минимуму, не без этого, но в целом проект как правило собирался и работал на новом стандарте без всякого "глубокого рефакторинга", а новый код (с конструкциями из новых стандартов) всегда можно было встраивать прямо "посреди старого" без особых проблем.

Много раз переходили на новые версии, в том числе и в крупных проектах. И проблемы возникли только один раз при переходе на C++11 (правда еще не получается использовать С++23, но он и не очень нужен).

Если Rust сможет подерживать свою экосистему в течении десятилетий без поломок старого кода (ведь старый код на С++ успешно компилировался при указании -std=с++98 или с++03), то честь ему и хвала, но сейчас прошло еще слишком мало времени для подобных выводов.

Скорее всего не раньше чем заведут ISO стандарт. А пока есть только честное слово поддержки любого кода с лексики 1.0.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации