如何在Rust类型签名中减少重复?

4

我有以下可用代码,但不是很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);
    }
}

我有很多重复的<'a, G, E, N, EW, NW, ER, NOW, EOW>,通常似乎所有这些特性都占用了很多空间。这只是糟糕的代码,还是我做错了什么?

上下文

游乐场


关联类型(例如GraphBase特征中的EdgeIdNodeId)并不总是需要指定。看看是否可以从实现中删除ENEWNW。我没有测试过,但您应该能够通过编写G::EdgeId等来使用这些类型。 - Aloso
一个用于实验的playground链接会非常棒! - Aloso
我刚刚添加了一个游乐场链接。 - timthelion
1个回答

5

关联类型并不总是需要有自己的类型参数。例如,您可以在限定中编写G::EdgeId,而不必拥有单独的参数E

我调整了播放链接中的代码以减少类型参数的数量。这里是更新后的链接。例如,Overlay现在具有4个而不是8个类型参数:

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,
}

请注意,我已经删除了G::NodeIdG::EdgeId中不必要的Copy + Eq + Hash特征边界。此外,G在特征边界中不再是引用,这可能会导致生命周期问题,但如果需要,这些问题可以得到解决。

我得稍微调整一下,这样我就可以在叠加层中引用图表而不是复制图表,但这样更好。我甚至也能够摆脱ER参数! https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=63905b2f4205317a17efae3fa5d47ede - timthelion
1
@timthelion 实际上,如果您使用类似 Overlay <&Graph,_,_,_> 这样的东西,因为&Graph实现了GraphBase特征,您仍然可以在我的解决方案中存储对图形的引用。 - Aloso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接