Generics 如何在Rust中模拟通用动态调度?

Generics 如何在Rust中模拟通用动态调度?,generics,rust,dynamic-dispatch,Generics,Rust,Dynamic Dispatch,我用在F#中学到的一个技巧来模拟存在类型,我想看看这在Rust中是否有效: /* To replicate: type SuperArrow<'a, 'b> = | Fn of (('a -> 'b) * string) | Compose of SuperArrowCompose<'a,'b> and SuperArrowCompose<'a,'b> = abstract member eval : SuperArrowCo

我用在F#中学到的一个技巧来模拟存在类型,我想看看这在Rust中是否有效:

/*
To replicate:
type SuperArrow<'a, 'b> = 
    | Fn of (('a -> 'b) * string)
    | Compose of SuperArrowCompose<'a,'b>
and SuperArrowCompose<'a,'b> = 
    abstract member eval : SuperArrowComposeEvaluator<'a, 'b, 'r> -> 'r
and SuperArrowComposeEvaluator<'a, 'b, 'r> = 
    abstract member apply<'c> : SuperArrow<'a, 'c> -> SuperArrow<'c, 'b> -> 'r
*/

//#[derive(Debug)]
struct MyFnWrapper<A, B> {
    f: Box<Fn(A) -> B>,
    n: String,
}

impl<A, B> MyFnWrapper<A, B> {
    pub fn new<F: 'static + Fn(A) -> B>(f: F, s: String) -> Self {
        MyFnWrapper {
            f: Box::new(f),
            n: s,
        }
    }
}

trait SuperArrowComposeEval<A, B, R> {
    fn apply<C>(&self, &SuperArrow<A, C>, &SuperArrow<C, B>) -> R;
}

trait SuperArrowCompose<A, B> {
    fn eval<R, E: SuperArrowComposeEval<A, B, R>>(&self, &E) -> R;
}

struct SuperArrowComposeImpl<A, B, C> {
    fnA: Box<SuperArrow<A, C>>,
    fnB: Box<SuperArrow<C, B>>,
}

impl<A, B, C> SuperArrowComposeImpl<A, B, C> {
    fn new(fnA: SuperArrow<A, C>, fnB: SuperArrow<B, C>) {
        SuperArrowComposeImpl {
            fnA: Box::new(fnA),
            fnB: Box::new(fnB),
        }
    }
}

impl<A, B, C> SuperArrowCompose<A, B> for SuperArrowComposeImpl<A, B, C> {
    fn eval<R, E: SuperArrowComposeEval<A, B, R>>(&self, evaler: &E) -> R {
        evaler.eval::<C>(self.fnA, self.fnB)
    }
}

//#[derive(Debug)]
enum SuperArrow<A, B> {
    Function(MyFnWrapper<A, B>),
    Compose(Box<SuperArrowCompose<A, B>>),
}

它需要是泛型的,以允许它在返回类型上是泛型的,但同时它需要是动态的,以隐藏连接两个函数的特定
C
类型。

除非我在这里遗漏了一个技巧,否则我认为我不需要任何技巧。这个技巧最好的部分是它始终保留类型——据我所知,任何类型都更类似于.NET中的对象。除非我在这里遗漏了一个技巧,否则我认为任何类型都不是我想要的。这个技巧最好的部分是它始终保留类型——据我所知,任何类型都更类似于.NET中的对象。