patternrustModerate
Is there any way to restrict a generic type to one of several types?
Viewed 0 times
restrictanyseveralwayonegenerictypetypesthere
Problem
I'm trying to create a generic struct which uses an "integer type" for references into an array. For performance reasons I'd like to be able to specify easily whether to use
Is there any way to express this?
u16, u32 or u64. Something like this (which obviously isn't valid Rust code):struct Foo { ... }Is there any way to express this?
Solution
Sometimes you may want to use an
One advantage of making a new type over implementing a new trait for existing types is that you can add foreign traits and inherent behavior to the new type. You can implement any traits you like for
Another thing to note: while you can generally always make a new type and implement a trait for it, an enum is "closed": you can't add new types to
"Performance reasons" is a bit ambiguous, but if you're thinking of storing a lot of
would waste a ton of space over storing a million
Now you only have one simple trait bound on
See Also
enum rather than a generic type with a trait bound. For example:enum Unsigned {
U16(u16),
U32(u32),
U64(u64),
}
struct Foo { x: Unsigned, ... };One advantage of making a new type over implementing a new trait for existing types is that you can add foreign traits and inherent behavior to the new type. You can implement any traits you like for
Unsigned, like Add, Mul, etc. When Foo contains an Unsigned, implementing traits on Unsigned doesn't affect the signature of Foo like it would to add them as bounds on Foo's parameter (e.g. Foo + PartialCmp + ...>). On the other hand, you do still have to implement each trait.Another thing to note: while you can generally always make a new type and implement a trait for it, an enum is "closed": you can't add new types to
Unsigned without touching the rest of its implementation, like you could if you used a trait. This may be a good thing or a bad thing depending on what your design calls for."Performance reasons" is a bit ambiguous, but if you're thinking of storing a lot of
Unsigneds that will all be the same internal type, and this:struct Foo([Unsigned; 1_000_000]);would waste a ton of space over storing a million
u16s, you can still make Foo generic! Just implement From, From, and From for Unsigned and write this instead:struct Foo>([T; 1_000_000]);Now you only have one simple trait bound on
T, you're not wasting space for tags and padding, and functions that deal with T can always convert it to Unsigned to do calculations with. The cost of the conversion may even be optimized away entirely.See Also
- Should I use enum to emulate the polymorphism or use trait with Box instead?
Code Snippets
enum Unsigned {
U16(u16),
U32(u32),
U64(u64),
}
struct Foo { x: Unsigned, ... };struct Foo([Unsigned; 1_000_000]);struct Foo<T: Into<Unsigned>>([T; 1_000_000]);Context
Stack Overflow Q#40776020, score: 29
Revisions (0)
No revisions yet.