2015-10-29 44 views
3

我正在尝试开发一种批处理系统。其中我想使用某种Process结构,它拥有所有与流程相关的部分。当前实现使用PhantomData执行该类型的约束:避免结构中的PhantomData强制执行类型约束

pub struct Process<P: Producer<U>, T: Transformer<U, V>, C: Consumer<V>, U,V> 
{ 
    producer: P, 
    transformer: T, 
    consumer: C, 
    p1: PhantomData<U>, 
    p2: PhantomData<V>, 
} 

的想法是,类型由Producer发射将由Transformer可以使用(也许为不同的类型)和所消耗由Consumer。因此类型必须匹配。

Process结构应该拥有执行Producer,TransformerConsumer特征的项目。我想这就是为什么我需要使用类型参数。既然不能直接使用特质像

... 
producer: Producer<U>, 
... 

,因为在编译时未知大小的。

有没有更好的方法来做到这一点?我对Rust很新,所以我可能会在错误的方向思考。

该解决方案有效,但与PhantomData字段看起来有点奇怪。也许这只是PhantomData用于?

回答

8

类型的参数,而是你要相关类型:

trait Producer { 
    type Output; 
    fn produce(&self) -> Self::Output; 
} 

trait Transformer { 
    type Input; 
    type Output; 
    fn transform(&self, val: Self::Input) -> Self::Output; 
} 

trait Consumer { 
    type Input; 
    fn consume(&self, val: Self::Input); 
} 

struct Process<P, T, C> 
    where P: Producer, 
      T: Transformer<Input = P::Output>, 
      C: Consumer<Input = T::Output> 
{ 
    producer: P, 
    transformer: T, 
    consumer: C, 
} 

impl<P, T, C> Process<P, T, C> 
    where P: Producer, 
      T: Transformer<Input = P::Output>, 
      C: Consumer<Input = T::Output> 
{ 
    fn run(&self) { 
     let a = self.producer.produce(); 
     let b = self.transformer.transform(a); 
     self.consumer.consume(b); 
    } 
} 

struct MakeNum; 
impl Producer for MakeNum { 
    type Output = u8; 
    fn produce(&self) -> u8 { 41 } 
} 

struct AddOne; 
impl Transformer for AddOne { 
    type Input = u8; 
    type Output = u8; 
    fn transform(&self, val: u8) -> u8 { val + 1 } 
} 

struct PrintNum; 
impl Consumer for PrintNum { 
    type Input = u8; 
    fn consume(&self, val: u8) { println!("Value was {}", val) } 
} 

fn main() { 
    let process = Process { 
     producer: MakeNum, 
     transformer: AddOne, 
     consumer: PrintNum, 
    }; 

    process.run(); 
} 

虽然我通常不会增加对struct正确的,我只希望有它的impl这也将有一个在where条款new确保约束的方法。

+0

哇,谢谢!这正是我正在寻找的东西,它看起来不再滥用PhantomData;) –