How should I reduce repetition in rust type signatures?

霸气de小男生 提交于 2020-05-23 09:42:46

问题


I have the following working code that isn't very DRY:

impl<'a, G, E, N, EW, NW, ER, NOW, EOW> Overlay<'a, G, E, N, EW, NW, ER, NOW, EOW>
where
    &'a G: GraphBase<EdgeId = E, NodeId = N> +
           Data<EdgeWeight = EW, NodeWeight = NW> +
           DataMap,
    ER: EdgeRef<Weight = EW, EdgeId = E, NodeId = N>,
    E: Copy + Eq + Hash,
    N: Copy + Eq + Hash,
{
    fn overlayed_elements(&'a self) -> OverlayedItems<'a, G, E, N, EW, NW, ER, NOW, EOW>{
        OverlayedItems{
            overlay: self,
            phase: Phase::Nodes(self.nodes.iter()),
            node_indexes: HashMap::new(),
        }
    }
    pub fn overlay_edge<'b>(&'b mut self, edge: ER, eow: EOW) {
        self.edges.insert(edge.id(), eow);
        self.edge_refs.insert(edge.id(), edge);
    }
    pub fn overlay_node<'b>(&'b mut self, node: N, now: NOW) {
        self.nodes.insert(node, now);
    }
    fn remove_edge<'b>(&'b mut self, edge: E) {
        self.edges.remove(&edge);
        self.edge_refs.remove(&edge);
    }
    fn remove_node<'b>(&'b mut self, node: N) {
        self.nodes.remove(&node);
    }
}

context

playground

I have a lot of repetition of <'a, G, E, N, EW, NW, ER, NOW, EOW> and it generally seems that all these trait thingamagigs are taking up a lot of space. Is this just bad code, or am I doing something wrong?


回答1:


Associated types do not always need to have their own type parameters. For example, you can write G::EdgeId in a bound instead of having a separate parameter E.

I adjusted the code in the playground link to reduce the number of type arguments. Here's the updated link. For example, Overlay now has 4 instead of 8 type arguments:

pub struct Overlay<G, ER, NOW, EOW>
where
    G: GraphBase + Data,
    ER: EdgeRef<Weight = G::EdgeWeight, EdgeId = G::EdgeId, NodeId = G::NodeId>,
{
    nodes: HashMap<G::NodeId, NOW>,
    edges: HashMap<G::EdgeId, EOW>,
    edge_refs: HashMap<G::EdgeId, ER>,
    graph: G,
}

Note that I removed the (unnecessary) Copy + Eq + Hash trait bounds for G::NodeId and G::EdgeId. Also, G is no longer behind a reference in the trait bounds, which might cause lifetime issues, but these can be fixed if necessary.



来源:https://stackoverflow.com/questions/60792494/how-should-i-reduce-repetition-in-rust-type-signatures

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!