Pointers 如何使用指针算法获取向量中元素的索引?
在C语言中,可以使用指针偏移量获取数组中元素的索引,例如:Pointers 如何使用指针算法获取向量中元素的索引?,pointers,vector,rust,Pointers,Vector,Rust,在C语言中,可以使用指针偏移量获取数组中元素的索引,例如: index = element_pointer - &vector[0]; 给定对数组中元素的引用,这在Rust中也应该是可能的 Rust能够从矢量元素中获取内存地址,将它们转换为usize,然后减去它们-在Rust中有更方便/惯用的方法吗?没有更简单的方法。我认为原因在于,很难保证给出答案的任何操作或方法只允许您将其用于Vec(或者更可能是切片)和该集合中的某些内容;Rust不想让你用一个指向另一个向量的引用来调用它 更惯用
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 tousize
”。这类似于答案为“just convert tousize
”的情况。对于常见情况,枚举很好,但是,有时函数可能(在特殊情况下)需要获取父对象,然后从向量中删除引用。其中传递索引是可能的,但不方便。枚举对于常见情况来说很好,但是有时函数(在特殊情况下)可能需要获取父级,然后从向量中删除引用。传递索引是可能的,但不方便。我通常建议在未选中的索引中使用debug\u断言
。我通常建议在未选中的索引中使用debug\u断言
。