У меня есть функция, которая десериализует содержимое из UnixStream в определения конкретных структур. Эти структуры могут быть одним из нескольких вариантов: изначально я выбрал перечисление, но clippy услужливо указал, что такой вариант, как
pub enum EventResponse {
Workspace(WorkspaceData),
Output(OutputData),
Mode(ModeData),
}
Неэффективен, если WorkspaceData очень большой и имеет намного больше полей, чем другие. Это увеличивает минимальный размер каждого варианта.
Чтобы обойти это, в моей десериализации fn I Box некоторые варианты:
pub enum EventResponse {
Workspace(Box<WorkspaceData>),
Output(OutputData),
Mode(ModeData)
}
pub fn receive_evt(&mut self) -> io::Result<event::EventResponse> {
let (evt_type, payload_bytes) = self.decode_msg()?;
let body = match evt_type.into() {
Event::Workspace => {
EventResponse::Workspace(Box::new(serde_json::from_slice::<event::WorkspaceData>(
&payload_bytes[..],
)?))
}
Event::Output => EventResponse::Output(serde_json::from_slice::<event::OutputData>(
&payload_bytes[..],
)?),
Event::Mode => EventResponse::Mode(serde_json::from_slice::<event::ModeData>(
&payload_bytes[..],
)?),
};
Ok(body)
}
Однако было бы неплохо, если бы мне не приходилось боксировать ни один из вариантов. С появлением impl Trait есть ли способ сделать это сейчас?
Я действительно хотел что-то вроде:
pub fn receive_evt_2<D: DeserializeOwned>(
&mut self,
) -> io::Result<EventResp<impl DeserializeOwned>> {
let (evt_type, payload_bytes) = self.decode_msg()?;
let evt_type = evt_type.into();
let body = match evt_type {
Event::Workspace => serde_json::from_slice::<event::WorkspaceData>(&payload_bytes[..])?,
Event::Output => serde_json::from_slice::<event::OutputData>(&payload_bytes[..])?,
Event::Mode => serde_json::from_slice::<event::ModeData>(&payload_bytes[..])?,
};
Ok(EventResp { evt_type, body })
}
Но это возвращает ошибку типа «Ожидаемый тип WorkspaceData, найденный тип OutputData».
Каковы мои варианты?
impl Trait в качестве возвращаемого типа является экзистенциальным, конкретным типом. Вам не нужно указывать его явно, но он по-прежнему может быть только одним фиксированным типом (возможно, в зависимости от параметров универсального типа для функции).
«Тип, который реализует Trait, но неизвестен до времени выполнения» — это dyn Trait, а не impl Trait. Возможно, вы могли бы определить EventResp так, чтобы он содержал элемент dyn Trait, но тогда вам просто нужно было бы вернуть Box<EventResp>. В настоящее время нет способа вернуть неразмерный тип бокса; для этого потребуется второй стек или что-то в этом роде (см. RFC № 1909).
@Stargateur, DeserializeOwned — черта из serde, я пытаюсь сказать, что функция возвращает что-то, что можно десериализовать. @trentcl спасибо, я полагаю, это то, что я ищу, да, это дубликат другого Q





но что такое
DeserializeOwned?