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>,
}
At the point of struct Partition, it is no longer interesting what Disks trait-bounds are. Through the language design, it is not possible to create a Disk with a handle what does not have Read + Seek + Write. Through this example is very simple, types might become extremely complex if they have multiple members with traits.
What I want is:
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 does abstractions by traits; so use a trait (not a type).
Specifically, Partition should depend on a generic parameter implementing a trait rather than on Disk<T: ...> itself.
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>,
}
Alternatively File could itself depend on an abstract partition.
Note that using this Volume trait, it is even possible to remove the generic parameter completely; as long as the Volume trait is object-safe and the object behind does not need to store a local reference:
struct Partition {
volume: Box<Volume>,
}
struct File {
partition: Partition,
}
It adds a tiny bit of over-head (a dynamic allocation + indirect calls), but gives you a single type instead of a family.
Another solution to only reduce verbosity is to introduce a new trait for specifically this purpose:
trait Volume: Read + Seek + Write {}
impl<T> Volume for T where T: Read + Seek + Write {}
Allows you to thereafter use the Volume trait as a short-hand for the sum of traits it represents. This does not abstract the disk, but is certainly convenient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With