在特征中使用特征作为类型参数的语法

时间:2015-11-23 04:06:40

标签: generics syntax rust traits

我有以下特点:

pub trait EventHandler<T: Stream<U>, U: Read + Write + AsRawFd> {
    fn on_data_received(&mut self, stream: T, buffer: Vec<u8>);
    fn on_stream_closed(&mut self, id: u32);
}

我尝试了以下内容:

pub type StreamList = LinkedList<Stream>产生:

error: wrong number of type arguments: expected 1, found 0

pub type StreamList = LinkedList<Stream<T: Read + Write + AsRawFd>>产生:

error: expected one of '!', '(', '+', ',', '::', '<', or '>', found ':'

使用Stream作为类型参数的正确语法是什么?

2 个答案:

答案 0 :(得分:2)

从语法上讲,我认为这就是你想要的:

trait OuterTrait<T> {
    fn use_type_parameter(t: T);
}

trait InnerTrait {}

type CombinedTypeOne<T: InnerTrait> = Option<OuterTrait<T>>;
type CombinedTypeTwo<T> where T: InnerTrait = Option<OuterTrait<T>>;

fn main() {}

从更广泛的意义上说,这是有道理的。定义类型时,它必须完全知道它是什么类型,或者具有类型参数并在使用站点完全指定。在您的示例中,类型StreamList的行为类似于完全指定。但是,右边说“放入任何具体类型”,所以你需要纠正这两个。

除此之外,特征约束在别名的“声明”部分,而不是“定义”部分。这反映了特征和函数定义的工作原理。

然而,第一个示例有此警告:

warning: trait bounds are not (yet) enforced in type definitions [E0122]
    type CombinedTypeOne<T: InnerTrait> = Option<OuterTrait<T>>;
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The detailed explanation for E0122

我认为第二个例子有相同的潜在问题,但警告丢失了 - 我猜这是一个应该报告的错误。我认为总的来说,这意味着你无法做你想做的事。

此外,您正在尝试将特征用作类型(在上面表示为Option<OuterTrait>。虽然在概念上可行,但我不知道如何实际构建一个看起来像这样的对象。它更可能是您想要的

之类的东西
type CombinedTypeOne<T, U: OuterTrait<T>> = Option<U>;
type CombinedTypeTwo<T, U> where U: OuterTrait<T> = Option<U>;

但抱怨未使用的类型参数。如果错误有意义,或者这个功能尚未强制执行的副作用,我无法推理:

error: type parameter `T` is unused [E0091]
    type CombinedTypeOne<T, U: OuterTrait<T>> = Option<U>;
                                                ^~~~~~~~~

答案 1 :(得分:0)

找到了答案from this question

pub trait StreamIo: Read + Write + AsRawFd {}
pub type StreamList = LinkedList<Stream<StreamIo>>;