简体   繁体   中英

Generically implementing a trait for all concrete types implementing another trait

I'm pretty new to rust, so this might be a stupid question with an obvious answer, but I don't know the answer yet. I've just read the book and then decided to implement some algorithms I'm familiar with, to get a feeling for the language. That, however, took me down a dark path to a side project that went a little deeper into the language than I had planned for...

I have indices into different arrays and strings and want to prevent using an index from one array to be used into another and things like that. So, I have defined new types for different kinds of indices, those with different domains, and for offsets between them. I don't allow comparisons between domains, I can subtract indices to get an offset and I can add and subtract indices and offsets and stuff like that. Further, I can define which types of objects indices can subscript, so an index into a string can only index a string and not, say, a suffix array, where another type is necessary.

I have a bunch of macros for defining what objects are allowed to do. For example, with this

def_offset!(Offset);
def_idx!(
    Idx
    with offset Offset
    with sub [
        Vec<T>[Idx] => T,
        [T][Idx] => T
    ]
);

Looking at the playground example, it's not possible to do what you want. This type of impl can't work:

impl<X, RHS> std::ops::Add<RHS> for X
where
    X: MyAdd<RHS>,
{
    type Output = X::Res;
    fn add(self, rhs: RHS) -> Self::Output {
        self.my_add(rhs)
    }
}

I fought it a bit more, and I think I might have a solution. Since I can't implement a trait for general types, but only types in my own crate, that is what I have to do. I didn't want to, because I wanted to use the types to define different operators, but I figured that there would be a way around that.

I define a type to contain information about the wrapped objects I will hold. Then I am going to wrap objects, and use instances of this type as tags, to give my wrappers different underlying types, and that way define operators.

// Any of the wrapped types should have this.
pub trait TypeInfo: Copy {
    type WrappedType: Copy + num::PrimInt;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM