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 u16
, u32
or u64
. Something like this (which obviously isn't valid Rust code):
struct Foo<T: u16 or u32 or u64> { ... }
Is there any way to express this?
Sometimes you may want to use an
enum
rather than a generic type with a trait bound. For example: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
, likeAdd
,Mul
, etc. and evenSliceIndex<[T]>
so that it can be used to index into a slice. WhenFoo
contains anUnsigned
, implementing traits onUnsigned
doesn't affect the signature ofFoo
like it would to add them as bounds onFoo
's parameter (e.g.Foo<T: Add<Output=Self> + 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
Unsigned
s that will all be the same internal type, and this:would waste a ton of space over storing a million
u16
s, you can still makeFoo
generic! Just implementFrom<u16>
,From<u32>
, andFrom<u64>
forUnsigned
and write this instead:Now you only have one simple trait bound on
T
, you're not wasting space for tags and padding, and functions that deal withT
can always convert it toUnsigned
to do calculations with. The cost of the conversion may even be optimized away entirely.See Also
For references into an array usually you'd just use a
usize
rather than different integer types.However, to do what you are after you can create a new trait, implement that trait for
u16
,u32
andu64
and then restrict T to your new trait.You may then also add methods onto
MyNewTrait
and theimpl
s to encapsulate the logic specific tou16
,u32
andu64
.