在C中,您可以使用指针偏移量来获取数组中元素的索引,例如:
index = element_pointer - &vector[0];
给定对数组中元素的引用,这在Rust中也是可能的。
虽然Rust能够从向量元素获取内存地址,将它们转换为usize
,然后减去它们 - 在Rust中有更方便/惯用的方法吗?
答案 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]