在别名中使用特征作为类型参数的语法
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>;
^~~~~~~~~
我有以下特点:
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>;
^~~~~~~~~