2015-11-04 3 views
3

Вот (несколько надуманный) пример, чтобы проиллюстрировать то, что я хотел бы сделатьОграничения, связанные типы признака

pub trait Node: Eq + Hash { 
    type Edge: Edge; 
    fn get_in_edges(&self) -> Vec<&Self::Edge>; 
    fn get_out_edges(&self) -> Vec<&Self::Edge>; 
} 

pub trait Edge { 
    type Node: Node; 
    fn get_src(&self) -> &Self::Node; 
    fn get_dst(&self) -> &Self::Node; 
} 

pub trait Graph { 
    type Node: Node; 
    type Edge: Edge; 
    fn get_nodes(&self) -> Vec<Self::Node>; 
} 

pub fn dfs<G: Graph>(root: &G::Node) { 
    let mut stack = VecDeque::new(); 
    let mut visited = HashSet::new(); 

    stack.push_front(root); 
    while let Some(n) = stack.pop_front() { 
     if visited.contains(n) { 
      continue 
     } 
     visited.insert(n); 
     for e in n.get_out_edges() { 
      stack.push_front(e.get_dst()); 
     } 
    } 
} 

Есть ли способ, чтобы выразить в Graph признак, что Graph::Node должны быть того же типа, как Graph::Edge::Node и что Graph::Edge должен быть того же типа, что и Graph::Node::Edge?

Я помню, как я читал что-то о функции (не реализованной в то время), которая позволила бы более сильные ограничения для такого рода вещей, но я не помню ее имени и не могу ее найти.

ответ

7

В определении Graph вы можете ограничить связанный тип связанного типа (!) Равным соответствующему связанному типу в Graph.

pub trait Graph { 
    type Node: Node<Edge=Self::Edge>; 
    type Edge: Edge<Node=Self::Node>; 
    fn get_nodes(&self) -> Vec<Self::Node>; 
} 
+0

Первоначально я думал, что это не сработает, потому что черты не имеют параметров типа, но это так! Благодаря! – ynimous

+0

ассоциированный тип является параметром типа –

Смежные вопросы