生锈;类型的命名空间中包含哪些类型?

In rust; what types are included in a type's Namespace?

我正在研究 petgraph 库的源代码,但我找不到 Graph::NodeId 类型的来源。

我可以看到函数astar accepts a type G (which can be a Graph)。 astar 期望在 G 的命名空间中有一个类型 NodeId

pub fn astar<G, F, H, K, IsGoal>(
    graph: G, 
    start: G::NodeId, 
    is_goal: IsGoal, 
    edge_cost: F, 
    estimate_cost: H
) -> Option<(K, Vec<G::NodeId>)> where
    G: IntoEdges + Visitable,
    IsGoal: FnMut(G::NodeId) -> bool,
    G::NodeId: Eq + Hash,
    F: FnMut(G::EdgeRef) -> K,
    H: FnMut(G::NodeId) -> K,
    K: Measure + Copy, 

我可以看到 Graph 被定义为

pub struct Graph<N, E, Ty = Directed, Ix = DefaultIx> {
    nodes: Vec<Node<N, Ix>>,
    edges: Vec<Edge<E, Ix>>,
    ty: PhantomData<Ty>,
}

不过,我不知道,看看 NodeId 类型是从哪里来的。我在源代码中看到它定义的唯一地方是在特征实现中 EdgeRef for EdgeReference

impl<'a, Ix, E> EdgeRef for EdgeReference<'a, E, Ix>
    where Ix: IndexType,
{
    type NodeId = NodeIndex<Ix>;
    type EdgeId = EdgeIndex<Ix>;
    type Weight = E;

    fn source(&self) -> Self::NodeId { self.node[0] }
    fn target(&self) -> Self::NodeId { self.node[1] }
    fn weight(&self) -> &E { self.weight }
    fn id(&self) -> Self::EdgeId { self.index }
}

但我不明白这种类型如何进入 Graph 的范围。

astar 有一个边界 G: IntoEdges + Visitable,其中 Visitable 定义为

pub trait Visitable: GraphBase { … }

GraphBase定义为

pub trait GraphBase {
    type EdgeId: Copy + PartialEq;
    type NodeId: Copy + PartialEq;
}

这就是允许 astar 使用 G::NodeId 的原因。基本上你有这个:

struct Graph;

trait GraphBase {
    type Type;
}

trait Visitable: GraphBase {}

impl GraphBase for Graph {
    type Type = u8;
}

impl Visitable for Graph {}

fn foo<G: Visitable>(_: G, _: G::Type) {}

fn main() {
    foo(Graph, 42);
}

(Permalink to the playground)