Dmitry_Optimizer
2026-07-22 17:22
Вопрос из разряда тех, что рано или поздно встаёт перед каждым, кто пишет системные библиотеки или сервисы с плагинами. Я сейчас работаю над pet-проектом — распределённый движок для потоковой обработки данных на Rust, и в очередной раз упираюсь в грабли ABI-совместимости. В Go, с её runtime-полиморфизмом и интерфейсами, казалось бы, всё проще: выкатил shared object с новым интерфейсом — и вперёд. Но Generics, которые наконец завезли в Go 1.18, внесли хаос. Теперь компилятор может сгенерировать несколько версий одной и той же функции для разных типов, и если вы используете пустой интерфейс (any) как границу — ловите падение с SIGSEGV при попытке загрузить либу, собранную с другой версией дженериков. Проблема в том, что Go не даёт гарантий на уровне бинарного интерфейса для обобщённого кода, и это не баг, а фича: они сознательно пожертвовали стабильностью ради скорости компиляции. В Rust, с другой стороны, мономорфизация Generics — это адская боль для плагинов. Если вы хотите динамическую загрузку .so, то дженерики придётся стирать (box/dyn), что убивает производительность на ровном месте. Я тестировал: вызов обобщённой функции через trait object даёт оверхед в 10–15% на микробенчмарках, и это на простых операциях. Плюс, Rust ещё не имеет стабильного ABI для dylib, хотя RFC с 2020 года болтается в обсуждениях. На практике, если вам нужна бинарная совместимость в Go — используйте интерфейсы без Generics и не трогайте any; в Rust — либо соберите всё статически, либо переходите на C ABI с unsafe-обёртками. Но оба пути — это костыли. Интересно, есть ли у кого-то опыт с решениями вроде FlatBuffers или Cap'n Proto для передачи данных между версиями библиотек? Или, может, кто-то пробовал WASM как промежуточный слой? Я склоняюсь к тому, что для серьёзных проектов проще забить на динамическую загрузку и пересобирать всё единым бинарником. Но это больно, когда у тебя микросервисы с разными релизными циклами. Короче, тема — боль, но без неё никуда. Жду аргументированных мнений, а не «а у меня работает». Точка.
👍 3