Por que esse programa não compila? E como consertar isso? Estou tentando serializar um enum genérico com serde, onde o tipo genérico é serializável.
use serde::{Deserialize, Serialize};
pub trait Row: for<'de> Deserialize<'de> + Serialize + Clone + Send + PartialEq {
fn key(&self) -> Option<u64> {
None
}
fn timestamp(&self) -> Option<u64> {
None
}
}
#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize)]
pub enum MessageContent<R: Row> {
// Other serializable members
Data(R),
}
fn main() {
// Create object of MessageContent and serialize.
}
O programa não compila devido a um limite de caracterÃstica redundante resultante da
Deserialize
expansão da macro derive.Considere o programa muito mais simples:
Se fizermos
cargo expand
as macros, veremos queR
tem umRow
limite e umserde::Deserialize<'de>
limite (nawhere
cláusula):Se tentarmos compilá-lo, um erro indicará que essa redundância aparentemente inofensiva não é permitida:
Para resolver isso, precisamos remover um dos limites redundantes. Para manter seu
Row
trait eMessageContent
enum iguais, podemos remover oDeserialize
limite extra da macro. Usamos o#[serde(bound(...))]
atributo para informar à macro queRaw
é o limite que tornaR
desserializável. Observe quefor<'de> Deserialize<'de>
é melhor escrito comoserde::de::DeserializeOwned
.Veja
cargo expand
como fica a nova saÃda:Os limites correspondem, o que aparentemente satisfaz o compilador Rust.
Por fim, só para você saber, colocar limites de caracterÃsticas em
struct
parâmetrosenum
genéricos não é apenas desencorajado , mas também é uma das causas desse problema.Esta versão também funciona e é, sem dúvida, mais idiomática. Ela só não permitiria que você usasse
<R as Row>::SomeAssociatedType
dentro doenum
: