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
的特征边界是什么已经不再有趣了。通过语言设计,不可能创建一个没有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
特质作为其所代表的特质总和的简写。这并没有抽象磁盘,但确实很方便。
关于generics - 如何在嵌套 Rust 类型中抽象泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40929867/