Отправка разных типов по одному каналу Rust (mpsc) - PullRequest
1 голос
/ 30 октября 2019

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

Получающий поток создается для обработки этих сообщений с использованиемследующее выражение соответствия.

let receiver_thread = match config.style.as_str() {
    "Type1" => start_recv_type1(receiver, config.clone(), log.clone()),
    "Type2" => start_recv_type2(receiver, config.clone(), log.clone()),
    "Type3" => start_recv_type3(receiver, log.clone()),
    _ => panic!("Wrong type!"),
};

Один из возможных типов, который может быть отправлен, - это String, а другой - это структура, которую я определил. Однако компилятор жалуется на несовпадающие типы в принимающем потоке. Глядя на то, как определены мои получатель и отправитель, я могу понять, почему это неверно, потому что он имеет следующий тип: std::sync::mpsc::Receiver<std::string::String>.

Глядя на мое выражение соответствия, я думаю, что разумнее создать более общую функцию дляинициализировать поток получения, но как я могу отправлять разные типы данных по одному каналу? Я искал и нашел возможное решение, используя перечисление с моей структурой и строкой в ​​качестве полей, но означает ли это, что мне придется изменить все определения моей функции, чтобы использовать этот синтаксис перечисления? Т.е. измените мои функции на ChannelTypes(StringMessage(String)) или ChannelTypes(StructMessage(factory::datatype::MyStruct))

enum ChannelTypes {
    StructMessage(factory::datatype::MyStruct),
    StringMessage(String),
}

1 Ответ

1 голос
/ 30 октября 2019

Один конкретный канал может отправлять только один тип данных. Как вы заметили, ваш отправитель имеет тип Sender<String>, а получатель имеет тип Receiver<String>. Так что оба зафиксированы на String. Обойти это невозможно (по уважительным причинам!)

На самом деле предпочтительным решением является использование перечисления , да. Фактически, вы пытаетесь эмулировать то, что enum сделал бы для вас: у вас есть тег , который описывает, какие данные ожидать. В своей попытке вы используете строки в качестве тегов. Но это плохая идея по множеству причин. Когда вы используете enum, используются целочисленные теги (намного лучше), и Rust обрабатывает их для вас. Гораздо более надежное решение.

Одно предложение: вам может показаться более полезным думать о вашем типе enum как о сообщении. Как это и есть: вы отправляете сообщение в другую ветку. И это сообщение может быть одним из множества разных типов. Получающий поток должен проверить, какой тип сообщения поступил, и затем может обработать его.

...