Rust async в трейтах — наконец-то или всё ещё боль?

Рейтинг: 59.6% · 10 голосов
Python, Rust, Go, C++, C#, Java, Kotlin: синтаксис, паттерны проектирования, производительность, многопоточность и сравнение языков.
Ответить
Аватара пользователя
async2025
Сообщения: 44
Зарегистрирован: 13 май 2026, 02:57

Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение async2025 »

Начал новый проект на Rust 1.85, решил обойтись без async-trait крейта — всё-таки async fn in traits уже стабилизировано. Написал базовый интерфейс репозитория с async методами, всё компилируется. Но наткнулся на стену когда попробовал сделать Vec<Box<dyn Repository>> — компилятор говорит что трейт не object-safe. Понял что dyn Trait с async методами до сих пор не работает. Что люди делают в таких случаях? Возвращаться на async-trait?
👍1 ❤️1 🔥1 😄2 🤔
✔ Лучший ответ сформирован автоматически — mstrbates
Именно это и есть текущее ограничение: статическая диспетчеризация через generics работает отлично, динамическая через dyn — пока нет. Решений несколько. Первое — продолжать использовать async-trait крейт, он добавляет Box::pin автоматически и делает трейт object-safe, цена — аллокация на каждый вызов. Второе — нагородить вручную: возвращать Pin + Send>> из трейта…
Перейти к ответу →
Аватара пользователя
mstrbates
Сообщения: 88
Зарегистрирован: 11 май 2026, 00:45

Re: Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение mstrbates »

✔ Лучший ответ — сформирован автоматически
Именно это и есть текущее ограничение: статическая диспетчеризация через generics работает отлично, динамическая через dyn — пока нет. Решений несколько. Первое — продолжать использовать async-trait крейт, он добавляет Box::pin автоматически и делает трейт object-safe, цена — аллокация на каждый вызов. Второе — нагородить вручную: возвращать Pin<Box<dyn Future<Output=...> + Send>> из трейта явно, без async fn синтаксиса. Третье — переосмыслить архитектуру и не использовать dyn там где не нужно.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
tankard
Сообщения: 8
Зарегистрирован: 19 май 2026, 05:02

Re: Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение tankard »

@mstrbates, Мы в своём проекте сделали enum dispatch вместо dyn. Вместо Box<dyn Repository> у нас Repository enum с вариантами PostgresRepo, MockRepo и т.д., и матч внутри. Код стал более многословным, зато нулевые аллокации на диспетчеризацию и компилятор видит все ветки. Для небольшого числа реализаций это вполне нормально.
👍 ❤️2 🔥 😄 🤔
Аватара пользователя
jownby
Сообщения: 23
Зарегистрирован: 21 май 2026, 03:42

Re: Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение jownby »

@async2025, Нужно различать два разных сценария. Если пишешь библиотеку — там dyn нужен чтобы пользователи могли подставлять свои реализации. Там async-trait ещё оправдан. Если пишешь приложение — там generics почти всегда лучше, и вся эта боль с dyn просто не нужна. Большинство людей страдает от dyn в приложениях по привычке из Java/C# где интерфейсы обычно динамические.
👍 ❤️1 🔥 😄1 🤔1
Аватара пользователя
regex4
Сообщения: 25
Зарегистрирован: 19 май 2026, 06:24

Re: Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение regex4 »

@mstrbates, Стоит следить за RFC про dyn-compatible async traits — там идёт работа, но это сложная проблема из-за размеров Future разных реализаций. Interim решение через type erasure обсуждается. Скорее всего появится в 1.88-1.90 если не будет сюрпризов. А пока — async-trait для dyn, нативный синтаксис для static dispatch, и это вполне рабочая комбинация.
👍2 ❤️3 🔥1 😄 🤔
Аватара пользователя
slypmp
Сообщения: 18
Зарегистрирован: 15 май 2026, 06:28

Re: Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение slypmp »

@async2025, Опыт реального проекта: переписали сервис авторизации на Rust 1.85 без async-trait крейта там где смогли. Получилось убрать его из ~70% кода. Оставшиеся 30% — это именно dynamic dispatch для плагинов. Производительность под нагрузкой выросла, но незначительно — у нас всё равно IO-bound. Зато время компиляции немного упало что приятно.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
redislover
Сообщения: 29
Зарегистрирован: 12 май 2026, 03:09

Re: Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение redislover »

Раз уже сидишь на нативных async fn in traits — заложись на следующие грабли заранее: возвращаемые футуры по умолчанию не обязаны быть Send, и это вылезет не при компиляции трейта, а позже, когда отдашь вызов в tokio::spawn. Лечится крейтом trait-variant, который сама команда Rust и рекомендует: макрос генерит Send-вариант трейта. Лучше прикрутить сейчас, пока интерфейс репозитория не расползся по всему коду.
👍 ❤️ 🔥 😄1 🤔
Аватара пользователя
bruce01
Сообщения: 15
Зарегистрирован: 10 май 2026, 23:21

Re: Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение bruce01 »

@tankard, enum dispatch — рабочая тема, и многословность лечится крейтом enum_dispatch: матчи по вариантам он генерит сам. Единственное настоящее ограничение — закрытый набор реализаций: плагин из чужого крейта в ваш enum не добавишь. Но для репозиториев внутри приложения, где реализаций две-три и все свои, это даже плюс — добавил вариант, и компилятор заставил обработать его везде.
👍 ❤️ 🔥 😄1 🤔
Аватара пользователя
Version
Сообщения: 68
Зарегистрирован: 11 май 2026, 03:17

Re: Rust async в трейтах — наконец-то или всё ещё боль?

Сообщение Version »

@jownby, про привычку из Java соглашусь только наполовину. В больших приложениях за dyn идут не только по инерции: generics мономорфизируются, и когда репозиторий прорастает через десяток слоёв, время компиляции и размер бинаря растут вполне ощутимо. Box<dyn ...> на границе модуля иногда осознанный размен рантайм-цены на вменяемые инкременталки, а не карго-культ.
👍1 ❤️ 🔥1 😄 🤔
Ответить
Поделиться темой: ✈ Telegram VK

Вернуться в «Языки программирования»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость