Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a trait with an associated type

struct A;
struct PropA;

struct B;
struct PropB;

trait AB{
    type prop;
    fn a(&self) -> ();
    fn b(&self, p: Self::prop) -> ();
}

impl AB for A{
    type prop = PropA;
    fn a(&self)->(){}
    fn b(&self, p: Self::prop) -> (){}
}
impl AB for B{
    type prop = PropB;
    fn a(&self)->(){}
    fn b(&self, p: Self::prop) -> (){}
}

fn get_a_or_b(s: &str) -> Option<Box<dyn AB<prop=_>>>{
    match s{
        "a" => Some(Box::new(A)),
        "b" => Some(Box::new(B)),
        _=> None
    }
}

Playground link

I am returning two different structs A&B based on a string input.

I get the type placeholder '_' is not allowed within types on item signatures when specifying associated type as placeholder.

like image 455
Slim Shady Avatar asked Mar 16 '26 10:03

Slim Shady


1 Answers

I believe there's a misconception here; dyn AB<Prop = A> and dyn AB<Prop = B> are different types, the first is a dynamic AB<Prop = A> and the second is a dynamic AB<Prop = B>. What this means is that you cannot leave generic types and associated types up to the dynamic aspect.

This is different than when the associated type is not mentioned:

fn foo<T: AB>() {
    let my_fn: fn(&T, T::Prop) = T::b;
}

Where we access the T::Prop instead of assigning it.


All types must be concrete, and dyn AB<Prop = A> on one branch, and dyn AB<Prop = B> on another branch is not concrete, but could be should you package it up under an enum:

enum AOrB {
    A(Box<dyn AB<Prop = A>>),
    B(Box<dyn AB<Prop = B>>),
}
like image 144
Optimistic Peach Avatar answered Mar 19 '26 14:03

Optimistic Peach