【问题标题】:Generic type for types implementing trait or dereferencing to trait实现 trait 或取消引用 trait 的类型的泛型类型
【发布时间】:2023-03-06 15:09:01
【问题描述】:

我正在寻找一种创建特征对象集合的方法。 但是我想接受实现给定特征的对象,或者包装和取消引用特征的对象。

trait TheTrait {
   // fn foo() -> ();
}

// "Direct" implementation
struct Implements {}
impl TheTrait for Implements {}

// "Proxy" implementation
struct DerefsTo {
    implements: Implements,
}
impl std::ops::Deref for DerefsTo {
    type Target = dyn TheTrait;
    fn deref(&self) -> &Self::Target {
        return &self.implements;
    }
}

fn main() -> () {
    let x1: Box<dyn TheTrait> = Box::new(Implements {}); // This is fine
    let x2: Box<dyn TheTrait> = Box::new(DerefsTo {implements: Implements {}}); // Trait TheTrait not implemented
    let x3: Box<dyn TheTrait> = Box::new(x1); // Trait TheTrait not implemented

    // Put x1, x2, x3 to collection, call foo
}

有没有办法做到这一点,可能不接触Implements 类型? 是否有任何通用方法通过公开实现特征的字段来实现特征,例如“包装器”类型?

【问题讨论】:

    标签: rust


    【解决方案1】:

    你可能想要

    impl<T: std::ops::Deref<Target = dyn TheTrait>> TheTrait for T
    

    这允许你写:

    trait TheTrait {
        fn foo(&self) -> ();
    }
    
    // "Direct" implementation
    struct Implements {}
    impl TheTrait for Implements {
        fn foo(&self) {
            println!("Implements::foo")
        }
    }
    
    // "Proxy" implementation
    struct DerefsTo {
        implements: Implements,
    }
    impl std::ops::Deref for DerefsTo {
        type Target = dyn TheTrait;
        fn deref(&self) -> &Self::Target {
            return &self.implements;
        }
    }
    
    impl<T: std::ops::Deref<Target = dyn TheTrait>> TheTrait for T {
        fn foo(&self) {
            self.deref().foo() // forward call
        }
    }
    
    fn main() -> () {
        let x1: Box<dyn TheTrait> = Box::new(Implements {});
        let x1_2: Box<dyn TheTrait> = Box::new(Implements {});
        let x2: Box<dyn TheTrait> = Box::new(DerefsTo {
            implements: Implements {},
        });
        let x3: Box<dyn TheTrait> = Box::new(x1_2);
        let vec = vec![x1, x2, x3];
        for x in vec {
            x.foo();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 2015-08-07
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多