Здравствуйте, ·, Вы писали:
·>Ну в том вопросе было про библиотеки и компоненты. Я вот до сих пор не понял как же компилятор ругается, если компоненты подключаются как зависимости. Вот конкретный пример. Допустим ты разрабатываешь rest-сервис. Тебе надо http-компонент и ssl-компонент. Компоненты разрабатываются и распространяются хрен знает когда и кем через какой-то публичный репо. Для твоего сервиса требуется http-3.1.4 (зависит от logger-1.0) и ssl-2.7.1 (зависит от logger-2.0). В твоём коде вообще ничего с logger нет, ты про него ничего не знаешь и знать не хочешь. Т.е. никакого "подключаешь несколько разных версий одной бинарной либы" у тебя нет. Несколько версий приходят транзитивно по зависимостям, у себя ты просто подключаешь соответствующие компоненты... и? В каком конкретно месте ругнётся компилятор?
Если типы logger не видны в публичном API http и ssl, то ни в каком. Если logger-2.0 не умеет уживаться в одном процессе с logger-1.0, это баг logger-2.0.
·>Допустим компилятор даже ругнулся. Как ты будешь делать "конвертирование между ее публичными типами"? В каком месте?
Там где они используются совместно. Если одна зависимость возвращает тип из подзависимости, и это значение надо передать в другую зависимость которая использует подзависимость другой версии.
·>Тебе придётся брать и изучать исходники чужих компонент, про которые ты ничего не знаешь и вообще не копенгаген и пытаться их совместить, пересобрать и передиплоить в свой приватный репо, в публичный — у тебя пермиссий нет. Собственно это и есть ад.
В 99.9% случаев достаточно чтения документации. Например, я использую в одной своей либе crypto-bigint 0.6 и 0.7-pre. Библиотека эллиптических кривых возвращает мне порядок кривой в виде типа crypto_bigint::Uint из 0.6, а мне надо передать это значение в другую библиотеку которая использует 0.7-pre. Я смотрю в
документацию, crypto_bigint::Uint можно конвертировать в указатель на массив цифр, можно сериализовать. Соответственно, в 0.7 можно восстановить из этого.
Насчет "пересобрать и передиплоить в свой приватный репо" я, если честно, вообще не понял о чем ты.
M>>О точном определении "ада зависимостей" — к ТС.
·>Ну я бы хотел просто понять какой же конкретно ад зависимостей по твоему пониманию был решён в rust?
Конфликт между совместимыми по API зависимостями. Т.к. в Расте уважают semver, любая более поздняя но совместимая по семверу либа может без проблем заменить более раннюю. Так что можно существенно облегчить граф зависимостей. Возможно, ТС имел в виду именно это.
·>Всё равно не понимаю причём тут компилятор. Обычно этим занимается package manager или project management tool. Т.к. работа идёт не на уровне сорцов, а на уровне пакетов/crates/dll/jar/etc. Во многих системах уже много лет есть механизмы описания и валидации графа зависимостей на совместимость... Что нового появилось в rust?
См. выше. Но, повторю, это лишь моя версия, я знаю что в Питоне граф зависимостей плоский, так что подход Раста по сравнению с ним — это шаг вперед. Но в JS зависимости в виде дерева, так что может там тоже зависимости объединяют. Что там есть "во многих системах" я не знаю, приводи конкретные примеры, сравним.
M>>·>Да и хуже того, ну обнаружил компилятор проблему, нарисовал тебе ошибку. Теперь тебе придётся разбираться что с чем не совместимо и как же это теперь решать и как собственно убедиться, что решение будет работать. И так при каждом минорном обновлении каждой зависимости.
M>>Нет. Подзависимости с версиями, например, 1.1 и 1.2 будут объединены в одну зависимость с версией как минимум 1.2. Если подзависимости требуют точные версии (=1.1 и =1.2), то резолвер выдаст ошибку (поэтому пинить версии в нормальных релизах считается дурным тоном и практически никогда не делается). Несколько копий зависимостей может быть только если их мажорные версии различаются. См. https://doc.rust-lang.org/cargo/reference/resolver.html
·>cargo — это вроде как не компилятор.
Нет, не компилятор, но объединение зависимостей в cargo убирает большинство "несовместимостей", так что компилятор ругается только на то что автоматически не исправить. "что с чем не совместимо" очевидно из ошибки компилятора, "как же это теперь решать" в большинстве случаев очевидно из документации, "как собственно убедиться, что решение будет работать" — для этого пишут тесты.
·>Сорцы чего? Я не понял. Возвращаюсь к примеру выше. Компилируя свой rest-сервис откуда возьмутся сорцы http/ssl/logger? Они все одновременно будут компилится?!
В Расте, да.
·>Если так, то что тебе, как разработчику rest-сервиса дадут 100500 ошибок компиляции в тоннах кода http и ssl компонент?
Откуда ошибки-то? Если подзависимости используются внутри зависимостей это их внутреннее дело, пока они не светят их типы в публичном API. И даже тогда ошибка будет только если ты тип из одной версии попытаешься передать куда-то где нужен тип из другой. Я регулярно вижу в дереве зависимостей один и тот же крейт разных версий. Проблем это не создает, кроме времени компиляции.