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

Pointers 如何使用指针算法获取向量中元素的索引?,pointers,vector,rust,Pointers,Vector,Rust,在C语言中,可以使用指针偏移量获取数组中元素的索引,例如: index = element_pointer - &vector[0]; 给定对数组中元素的引用,这在Rust中也应该是可能的 Rust能够从矢量元素中获取内存地址,将它们转换为usize,然后减去它们-在Rust中有更方便/惯用的方法吗?没有更简单的方法。我认为原因在于,很难保证给出答案的任何操作或方法只允许您将其用于Vec(或者更可能是切片)和该集合中的某些内容;Rust不想让你用一个指向另一个向量的引用来调用它 更惯用

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

index = element_pointer - &vector[0];
给定对数组中元素的引用,这在Rust中也应该是可能的


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

没有更简单的方法。我认为原因在于,很难保证给出答案的任何操作或方法只允许您将其用于
Vec
(或者更可能是切片)和该集合中的某些内容;Rust不想让你用一个指向另一个向量的引用来调用它

更惯用的做法是,一开始就避免这样做。由于生命周期的原因,您无法将引用存储到
Vec
中非常永久的
Vec
之外的任何位置,因此,当您已经获得引用时,您可能会手头有索引


特别是,例如,在迭代时,您将使用来迭代成对的
(索引和项)

没有更简单的方法。我认为原因在于,很难保证给出答案的任何操作或方法只允许您将其用于
Vec
(或者更可能是切片)和该集合中的某些内容;Rust不想让你用一个指向另一个向量的引用来调用它

更惯用的做法是,一开始就避免这样做。由于生命周期的原因,您无法将引用存储到
Vec
中非常永久的
Vec
之外的任何位置,因此,当您已经获得引用时,您可能会手头有索引


特别是,当迭代时,例如,您将使用迭代对
(索引和项)

因此,考虑到人们提出的指针和东西的问题;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
    }
}
fn未选中的索引(片:&[T],项:&T)->usize{
if::std::mem::size_of::()==0{
返回0;//对该案例执行您想执行的操作
}
(项作为*const u作为usize-slice.as_ptr()作为usize)
/std::mem::size_of::()
}
//注意:对于此处的零尺寸类型,您可以
//如果项as*const T==slice.as_ptr()返回一些(0)
//没有别的
fn索引(切片:&T],项目:&T)->选项{
设ptr=项目为*常数T;
如果
slice.as_ptr()ptr
{
一些(未选中的索引(切片、项目))
}否则{
没有一个
}
}
尽管如此,如果需要方法:

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> {
        // ...
    }
}
trait IndexOfExt{
fn未选中的索引(&self,item:&T)->usize;
fn索引(自身,项目:&T)->选项;
}
[T]的impl IndexOfExt{
fn未选中的索引(自身,项目:&T)->usize{
// ...
}
fn索引(自身,项目:&T)->选项{
// ...
}
}

然后你就可以用这个方法处理任何类型的
Deref
s到
[T]

所以,考虑到人们提出的指针和东西的问题;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
    }
}
fn未选中的索引(片:&[T],项:&T)->usize{
if::std::mem::size_of::()==0{
返回0;//对该案例执行您想执行的操作
}
(项作为*const u作为usize-slice.as_ptr()作为usize)
/std::mem::size_of::()
}
//注意:对于此处的零尺寸类型,您可以
//如果项as*const T==slice.as_ptr()返回一些(0)
//没有别的
fn索引(切片:&T],项目:&T)->选项{
设ptr=项目为*常数T;
如果
slice.as_ptr()ptr
{
一些(未选中的索引(切片、项目))
}否则{
没有一个
}
}
尽管如此,如果需要方法:

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> {
        // ...
    }
}
trait IndexOfExt{
fn未选中的索引(&self,item:&T)->usize;
fn索引(自身,项目:&T)->选项;
}
[T]的impl IndexOfExt{
fn未选中的索引(自身,项目:&T)->usize{
// ...
}
fn索引(自身,项目:&T)->选项{
// ...
}
}

然后,您可以对任何类型的
Deref
s to
[T]

使用此方法,这类似于答案为“just convert to
usize
”。这类似于答案为“just convert to
usize
”的情况。对于常见情况,枚举很好,但是,有时函数可能(在特殊情况下)需要获取父对象,然后从向量中删除引用。其中传递索引是可能的,但不方便。枚举对于常见情况来说很好,但是有时函数(在特殊情况下)可能需要获取父级,然后从向量中删除引用。传递索引是可能的,但不方便。我通常建议在未选中的索引中使用
debug\u断言
。我通常建议在未选中的索引中使用
debug\u断言