我正在尝试开发一种批处理系统。 在那里我想使用某种Process结构,它拥有所有与流程相关的部分。 当前的实现使用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 , Transformer和Consumer特性的项目。 我想这就是为什么我需要使用类型参数。 因为我不能直接使用这个特质
... producer: Producer<U>, ...因为编译时未知的大小。
有没有更好的方法来做到这一点? 我对Rust很新,所以我可能会在错误的方向思考。
该解决方案有效,但对于那些PhantomData字段看起来有点奇怪。 也许这只是PhantomData的用途?
I'm trying to develop a kind of batch system. Within that I'd like to use some kind of Process struct, which owns all process related parts. The current implementation uses PhantomData to enforce the type constraints:
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>, }The idea is that type emitted by the Producer will be used by the Transformer (maybe to a different type) and consumed by the Consumer. Therefore the types must match.
The Process struct should own the items implementing the Producer, Transformer and Consumer traits. I think that's why I need to use type parameters. Since I cannot use the the trait directly like
... producer: Producer<U>, ...because of the unknown size at compile time.
Is there a better way of doing this? I'm pretty new to Rust, so I might be thinking in the wrong direction.
The solution works, but it looks a bit odd with those PhantomData fields. Maybe that is just what PhantomData is used for?
最满意答案
您需要关联的类型而不是类型参数:
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本身中添加where子句,但我只是在impl上添加where子句,它也会有一个确保约束的new方法。
Instead of type parameters, you want associated types:
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(); }Although I wouldn't normally add the where clause on the struct proper, I'd just have it on the impl which would also have a new method that ensures the constraints just as well.
更多推荐
发布评论