Specifying generic parameter to belong to a small set of types

走远了吗. 提交于 2019-12-31 04:05:22

问题


Is it possible with to constrain a generic parameter to be one of the select few types without figuring out what traits precisely define those type? e.g.

impl<T> Data<T> where T == u32 || T == u64 

Sometimes it's tedious to figure out what all traits to add to where to get the types you want, and sometimes one wouldn't want to allow a type even when it makes syntactic sense because of semantics.


回答1:


You could use a marker trait for the types you want to support:

trait DataSupported {}

impl DataSupported for u64 {}
impl DataSupported for u32 {}

impl<T> Data<T> where T: DataSupported {}

As Pavel Strakhov mentioned, if you need to use this trait for a few impls and you need other trait bounds, then you can just make those traits as bounds of your marker trait instead, which will keep your impls terse:

trait DataSupported: Num + Debug {}



回答2:


You can use a macro to add implementations based on a list of types:

macro_rules! data_impl {
    ($($t: ty),+) => {
        $(
            impl Data<$t> {
                // methods go here
            }
        )+
    }
}

data_impl!(u32, u64, i32, i64);

It's probably worth adding #[allow(dead_code)] to each method to prevent warnings, since you'll be defining lots of specialised methods that may not be used in your application if you don't use them for every possible type. This is exactly the same thing that the compiler does anyway if you define methods over a parameter T (a process called monomorphisation). The difference is that the macro-generated methods are defined during the compiler's parse step (before linting) while monomorphisation happens later in the pipeline.



来源:https://stackoverflow.com/questions/42381185/specifying-generic-parameter-to-belong-to-a-small-set-of-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!