每个实例都有不同的关联类型

时间:2015-07-03 13:23:39

标签: types rust

有没有办法在rust中指定相关类型,这些类型对于每个实例都是不同的?或者有没有计划将其引入该语言?或者以任何其他方式实现这种行为?我认为scala有这个功能。

我需要此功能,例如,定义表示切片索引的类型,不需要对其进行范围检查。我不知道使用此功能的语法(如果存在)。所以我将使用我希望在以下示例中使用的那个。

// Each safe index has to implement this trait. 
pub trait SafeIndex {
    // Convert the safe index to an unsafe index.
    fn to_unsafe(&self) -> usize;
}

// Safe indexable
pub trait SafeIndexable {
    // The Item which is indexable.
    type Item;

    // In this context self.Index should be usable as index
    // without the need to do a range check.
    // This is a type alias which is distinct for each
    // instance. Therefore you need to specify an instance
    // (self) instead of a type name (Self) to access the type.
    // It is known, that each self.Index implements SafeIndex.
    type self.Index : SafeIndex;

    // Iterator of indices usable without range checking.
    type self.Indices : Iterator<Item = self.Index>;
    fn indices(&self) -> self.Indices;

    // Get item from index, without range checking.
    fn get<'s>(&'s self, index: self.Index) -> &'s Self::Item;
}

impl<I> SafeIndexable for &[I] {
    // The Item which is indexable.
    type Item = I;

    // This is a struct which is distinct for each
    // instance. Therefore you need to specify an instance
    // (self) instead of a type name (Self) to access the struct.
    struct self.IndexImpl {
        unsafe_index: usize,
    }
    impl SafeIndex for self.IndexImpl {
        fn to_unsafe(&self) -> usize {
            self.unsafe_index
        }
    }
    // This is the type alias which is distinct for each instance.
    type self.Index = self.IndexImpl;

    // Iterator of indices usable without range checking.
    struct self.IndicesImpl {
        begin: usize,
        end: usize,
    }
    impl Iterator for self.IndicesImpl {
        type Item = self.Index;
        fn next(&self) -> Option<Self::Item> {
            if self.begin != self.end {
                let cur = self.begin;
                self.begin += 1;
                Some(Self::Item{unsafe_index: cur})
            } else {
                None
            }
        }
    }
    type self.Indices = self.IndicesImpl;
    fn indices(&self) -> self.Indices {
        self.IndicesImpl{begin:0, end: self.len()}
    }

    // Get item from index, without range checking.
    fn get<'s>(&'s self, index: self.Index) -> &'s Self::Item {
        unsafe {
            let ptr = &self[0] as *const I;
            &*ptr.offset(index.unsafe_index as isize) as &Self::Item
        }
    }
}

此功能有许多更有用的用例。例如,仅可生长的载体。

0 个答案:

没有答案