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

Syntax for using traits as type parameters in aliases

我有以下特点:

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 作为类型参数的正确语法是什么?

已找到答案 from this question

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

语法上,我想这就是你想要的:

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 就像是完全指定的一样。但是右边写的是"put in any concrete type",所以你需要纠正这两个。

除此之外,特征约束在别名的 "declaration" 部分,而不是 "definition" 部分。这反映了特征和函数定义的工作方式。

但是,第一个例子有这个警告:

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>;
                                                ^~~~~~~~~