2016-08-30 2 views
1

당신이 배열의 요소에 대한 참조 감안할 때 배열 내 요소의 인덱스를 얻을 수 오프셋 포인터, 예컨대 :포인터 연산을 사용하여 벡터의 요소 색인을 얻는 방법은 무엇입니까? C에서

index = element_pointer - &vector[0]; 

을 사용할 수 있습니다,이 역시 녹에 수 있어야한다.

녹이 벡터 요소에서 메모리 주소를 가져 오는 동안 usize으로 변환 한 다음 빼십시오 - 녹에서 더 편리하게/관용적 인 방법이 있습니까?

+0

이것은 [[& str] 사이의 바이트 오프셋을 얻는 방법]과 유사합니다 (https://stackoverflow.com/questions/38268529/how-to-get-the-byte-offset-between-str) * 대답은 "단지'usize'로 변환됩니다." – mcarton

답변

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]

+0

일반적으로'index_of_unchecked'에'debug_assert'를 권합니다. – ubsan

4

더 간단한 방법은 없습니다. 그 이유는 그 대답을 준 오퍼레이션이나 메소드가 Vec (또는 더 많은 가능성이있는 슬라이스)과 그 콜렉션 안의 어떤 것으로 만 사용할 수 있도록 보장하는 것이 어려울 것이라고 생각합니다. Rust는 다른 벡터에 대한 참조를 사용하여 Rust를 호출하는 것을 원하지 않습니다.

더 관용적 인 것은 처음에는 그것을 할 필요가 없다는 것입니다. 어쨌든 Vec에 참조를 저장할 수는 없으므로 어쨌든 참조가있을 때 색인을 준비하는 것이 좋습니다.

특히, 반복 할 때 enumerate을 사용하면 (index, &item) 쌍을 반복 할 수 있습니다.

+0

열거 형은 일반적인 경우에 적합하지만 함수가 (특별한 경우) 부모를 가져와 벡터에서 참조를 제거해야하는 경우가 있습니다. 색인을 지나는 것이 가능하지만 불편합니다. – ideasman42

관련 문제