Rust не может отправлять развернутые данные результата через точку ожидания

Рассмотрим следующий код:

use std::error::Error;

use tokio::sync::mpsc;

fn gen_data() -> Result<i32, Box<dyn Error>> {
    Ok(42)
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (tx, rx) = mpsc::channel(10);

    // TODO: future cannot be sent between threads safely the trait `Send` is not implemented for `dyn std::error::Error`
    tokio::spawn(async move {
        if let Ok(data) = gen_data() {
            tx.send(data).await;
        }
    });

    while let Some(res) = rx.recv().await {
        println!("{}", res);
    }

    Ok(())
}

У меня есть общее представление о том, что ошибка пытается сказать. Это говорит о том, что Err результат моей gen_data функции не удаляется до того, как я awaiting?

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

Как я могу реорганизовать код, чтобы он скомпилировался?

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
0
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В реальных приложениях вам, вероятно, следует избегать использования Box<dyn Error> и вместо этого создавать собственное перечисление ошибок, которое может представлять каждую ошибку, которая может возникнуть в вашем приложении. См., например, эта почта, поясняющий, как этого добиться. Итак, если вы думаете о рефакторинге своего кода, возможно, сейчас самое время изменить способ обработки ошибок.

Однако, если вы хотите сохранить свою ошибку в виде трейт-объектов, вам просто нужно заставить их быть Send, изменив Box<dyn Error> на Box<dyn Error + Send>. Точно так же, если вам нужно, чтобы они были также Sync, используйте Box<dyn Error + Send + Sync>. Единственная проблема этого подхода заключается в том, что это ограничение будет распространяться на остальную часть вашего кода: если в какой-то момент функция вернет только Box<dyn Error>, то вы не сможете получить Box<dyn Error + Send> обратно, поэтому даже обычные (не async) функции будут должны возвращать ошибки, которые также являются Send, что немного странно.

Другие вопросы по теме