Why must the associated type be specified in a collection of references to types implementing a trait?

前端 未结 3 1838
醉酒成梦
醉酒成梦 2020-12-11 17:31

Here is an offending example:

// Some traits
trait Behaviour {
    type Sub: SubBehaviour;
}
trait SubBehaviour {}

// Some implementations of these traits
s         


        
3条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-11 17:45

    So the answer to your first question is covered by Tim's answer and is correct, you might not want your Example to be generic. In that case, you need to use some sort of type erasure:

    // Some traits
    trait Behaviour {
        type Sub: SubBehaviour;
    }
    trait SubBehaviour {}
    
    // Some implementations of these traits
    struct A;
    impl Behaviour for A {
        type Sub = B;
    }
    
    struct B;
    impl SubBehaviour for B {}
    
    struct AnyBehaviour {
        closure: Box,
    }
    impl AnyBehaviour {
        fn new>(b: &T) -> Self {
            let closure = || {
                //let sub = T::Sub::new();
                println!("Can use T here");
            };
    
            AnyBehaviour {
                closure: Box::new(closure),
            }
        }
    }
    
    // Struct that holds a collection of these traits.
    struct Example {
        behaviours: Vec,
    }
    
    impl Example {
        fn add_behaviour>(&mut self, b: &T) {
            self.behaviours.push(AnyBehaviour::new(b));
        }
    }
    
    fn main() {
        let b = A;
        let mut e = Example {
            behaviours: Vec::new(),
        };
        e.add_behaviour(&b);
    }
    

    Within the closure, you have access to all the types needed call the traits functions with whatever subtype needed.

    Why this happens, is mostly because you actually need a definition of the associated type in order for the trait to be "complete" so the compiler can work with it. Tim's answer answers that by the definition to be higher up in the chain (outside of Example) instead of inside.

提交回复
热议问题