Мне действительно нужно понижение в Rust?

#rust

#Ржавчина

Вопрос:

Предположим, у меня есть 2 черты:

 pub trait VpnProvider {
    fn connect();
}

pub trait RtspClient {
    fn connect();
    fn set_vpn_provider(Arc<Mutex<dyn VpnProvider>>);
}
  

Теперь предположим, что я хочу сохранить их оба на Stream . Я хочу это сделать, потому что хочу, чтобы в моих потоках были части, которые можно переключать в реальном времени. Так что я могу переключить rtsp_client , если захочу vpn_provider , и т. Д. Вот почему я использую «указатели на реализацию».

 struct Stream {
    pub rtsp_client: Arc<Mutex<dyn RtspClient>>,
    pub vpnProvider: Arc<Mutex<dyn VpnProvider>>
}
  

Хорошо, итак, rtsp_client имеет свой собственный VpnProvider указатель. Клиент rtsp должен использовать это VpnProvider для отправки пакетов. Но поскольку может быть много VPN-клиентов (OpenVPN, Wireguard и т. Д.), У них может не быть общего интерфейса. Итак, чтобы rtsp-клиент мог взаимодействовать с подключением, он должен понизиться до определенного типа VPN и взаимодействовать с ним.

Вот как я это делаю в C : он использует понижение до соответствующего типа, используя std::dynamic_pointer_cast<OpenVPN> (например) on std::shared_ptr<VpnProvider> , и проверяет, работает ли понижение, в противном случае он пробует другой тип.

Я не мог думать о другом шаблоне проектирования. Однако я стараюсь избегать использования этих библиотек Rust, которые имитируют понижение. Если нет официальной поддержки понижения в языке, то может быть лучший способ решить эту проблему.

Комментарии:

1. Какой смысл иметь VpnProvider признак, если вы не можете использовать его без понижения до конкретного типа? Разве все эти детали, относящиеся к конкретному клиенту, не должны быть абстрагированы с помощью функции? Вы говорите, что «у них может не быть общего интерфейса», но черта — это общий интерфейс. Если признак недостаточно выразителен или достаточно общий, чтобы позволить вам делать то, что вам нужно, с помощью a VpnProvider , тогда, возможно, вам просто нужно добавить к нему больше функциональности, чтобы понижение не было необходимым.

2. Если это не разумное решение, все, что вы можете сделать с понижением, вы могли бы сделать с enum помощью instead без потери общности (потому что понижение требует, чтобы вы знали все возможные типы на сайте использования, точно так же, как enum это делают s). Так что, может быть, превращение VpnProvider в enum приемлемую альтернативу?

3. @trentcl да! Это то, что я искал, спасибо 🙂