简体   繁体   English

"为实现另一个特征的所有具体类型一般地实现一个特征"

[英]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.我对 rust 很陌生,所以这可能是一个愚蠢的问题,答案很明显,但我还不知道答案。 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...然而,这让我走上了一条黑暗的道路,进入了一个比我计划的语言更深入的副项目......

Anyway, I'm now playing around with some code for working with indices and offsets in some algorithms in a type-safe way.无论如何,我现在正在使用一些代码来以类型安全的方式处理某些算法中的索引和偏移量。 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.此外,我可以定义哪些类型的对象索引可以下标,因此字符串的索引只能索引字符串,而不是后缀数组,其中需要另一种类型。

This mostly works.这主要是有效的。 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 不能工作:

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.由于我无法为一般类型实现特征,而只能在我自己的 crate 中实现类型,这就是我必须做的。 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.我不想这样做,因为我想使用这些类型来定义不同的运算符,但我认为会有办法解决这个问题。

Here is what I have right now.这是我现在所拥有的。 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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