你如何在嵌套的 Rust 类型中抽象泛型?
How do you abstract generics in nested Rust types?
struct Disk<T: Read + Seek + Write> {
handle: T,
}
struct Partition<T: Read + Seek + Write> {
disk: Disk<T>,
}
struct File<T: Read + Seek + Write> {
partition: Partition<T>,
}
在 struct Partition
点,Disk
的 trait-bounds 是什么不再有趣。通过语言设计,不可能创建句柄没有 Read + Seek + Write
的 Disk
。通过这个例子非常简单,如果类型有多个具有特征的成员,类型可能会变得非常复杂。
我想要的是:
struct Disk<T: Read + Seek + Write> {
handle: T,
}
type ExDisk = FIXME;
struct Partition {
disk: ExDisk,
}
struct File {
partition: Partition,
}
How do you abstract generics in nested types?
Rust 通过特征进行抽象;所以使用特征(不是类型)。
具体来说,Partition
应该依赖于实现特征的通用参数而不是 Disk<T: ...>
本身。
trait Volume {}
struct Disk<T: Read + Seek + Write> {
handle: T,
}
impl<T: Read + Seek + Write> Volume for Disk<T> {}
struct Partition<V: Volume> {
volume: V,
}
struct File<V: Volume> {
partition: Partition<V>,
}
或者 File
本身可以依赖于抽象分区。
请注意,使用此 Volume
特征,甚至可以完全删除泛型参数;只要 Volume
特征是对象安全的 和 后面的对象不需要存储本地引用:
struct Partition {
volume: Box<Volume>,
}
struct File {
partition: Partition,
}
它增加了一点点开销(动态分配 + 间接调用),但是给你一个单一的类型而不是一个系列。
另一个只减少冗长的解决方案是引入一个新的 trait
专门用于此目的:
trait Volume: Read + Seek + Write {}
impl<T> Volume for T where T: Read + Seek + Write {}
允许您此后使用 Volume
特征作为它所代表的特征总和的简写。这并没有抽象磁盘,但肯定很方便。
struct Disk<T: Read + Seek + Write> {
handle: T,
}
struct Partition<T: Read + Seek + Write> {
disk: Disk<T>,
}
struct File<T: Read + Seek + Write> {
partition: Partition<T>,
}
在 struct Partition
点,Disk
的 trait-bounds 是什么不再有趣。通过语言设计,不可能创建句柄没有 Read + Seek + Write
的 Disk
。通过这个例子非常简单,如果类型有多个具有特征的成员,类型可能会变得非常复杂。
我想要的是:
struct Disk<T: Read + Seek + Write> {
handle: T,
}
type ExDisk = FIXME;
struct Partition {
disk: ExDisk,
}
struct File {
partition: Partition,
}
How do you abstract generics in nested types?
Rust 通过特征进行抽象;所以使用特征(不是类型)。
具体来说,Partition
应该依赖于实现特征的通用参数而不是 Disk<T: ...>
本身。
trait Volume {}
struct Disk<T: Read + Seek + Write> {
handle: T,
}
impl<T: Read + Seek + Write> Volume for Disk<T> {}
struct Partition<V: Volume> {
volume: V,
}
struct File<V: Volume> {
partition: Partition<V>,
}
或者 File
本身可以依赖于抽象分区。
请注意,使用此 Volume
特征,甚至可以完全删除泛型参数;只要 Volume
特征是对象安全的 和 后面的对象不需要存储本地引用:
struct Partition {
volume: Box<Volume>,
}
struct File {
partition: Partition,
}
它增加了一点点开销(动态分配 + 间接调用),但是给你一个单一的类型而不是一个系列。
另一个只减少冗长的解决方案是引入一个新的 trait
专门用于此目的:
trait Volume: Read + Seek + Write {}
impl<T> Volume for T where T: Read + Seek + Write {}
允许您此后使用 Volume
特征作为它所代表的特征总和的简写。这并没有抽象磁盘,但肯定很方便。