Итак, учитывая проблемы, которые люди подняли с помощью указателей и прочее; лучший способ, имхо, чтобы сделать это:
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]
Это похоже на * [Как получить смещение байта между '& str'] (https://stackoverflow.com/questions/38268529/how-to-get-the-byte-offset-between-str) * где ответ был «просто конвертируется в' usize' ». – mcarton