如何使用指针算法获取向量中元素的索引?

时间:2016-08-30 05:51:22

标签: pointers vector rust

在C中,您可以使用指针偏移量来获取数组中元素的索引,例如:

index = element_pointer - &vector[0];

给定对数组中元素的引用,这在Rust中也是可能的。

虽然Rust能够从向量元素获取内存地址,将它们转换为usize,然后减去它们 - 在Rust中有更方便/惯用的方法吗?

2 个答案:

答案 0 :(得分:4)

没有更简单的方法。我认为原因是很难保证给你答案的任何操作或方法只允许你使用a Vec(或更可能的切片)和该集合内的东西; Rust不会允许你通过引用另一个向量来调用它。

更惯用的是避免首先需要这样做。由于生命周期的原因,您无法在Vec之外的任何地方将引用存储到Vec,因此当您获得该引用时,您很可能将该索引设为方便无论如何参考。

特别是,例如,在迭代时,您使用enumerate来迭代对(index, &item)

答案 1 :(得分:1)

所以,考虑到人们提出的指针和内容的问题;最好的办法,imho,这样做是:

fn index_of_unchecked<T>(slice: &[T], item: &T) -> usize {
    if ::std::mem::size_of::<T>() == 0 {
        return 0; // do what you will with this case
    }
    (item as *const _ as usize - slice.as_ptr() as usize)
    / std::mem::size_of::<T>()
}

// note: for zero sized types here, you
// return Some(0) if item as *const T == slice.as_ptr()
// and None otherwise
fn index_of<T>(slice: &[T], item: &T) -> Option<usize> {
    let ptr = item as *const T;
    if
        slice.as_ptr() < ptr && 
        slice.as_ptr().offset(slice.len()) > ptr
    {
        Some(index_of_unchecked(slice, item))
    } else {
        None
    }
}

但是,如果你想要方法:

trait IndexOfExt<T> {
    fn index_of_unchecked(&self, item: &T) -> usize;
    fn index_of(&self, item: &T) -> Option<usize>;
}

impl<T> IndexOfExt<T> for [T] {
    fn index_of_unchecked(&self, item: &T) -> usize {
        // ...
    }
    fn index_of(&self, item: &T) -> Option<usize> {
        // ...
    }
}

然后您就可以将此方法用于Deref[T]

的任何类型