あなたは配列内の要素のインデックスを取得するためのオフセットポインタを使用することができますCでは、例えば:ポインタ算術を使用してベクトルの要素のインデックスを取得する方法は?
配列の要素への参照を考えるindex = element_pointer - &vector[0];
、これはあまりにも錆に可能なはずです。
ベクトル要素からメモリアドレスを取得する能力がありますが、usize
に変換してから、それらを減算します.Rustでこれを行うにはもっと便利で便利ですか?
あなたは配列内の要素のインデックスを取得するためのオフセットポインタを使用することができますCでは、例えば:ポインタ算術を使用してベクトルの要素のインデックスを取得する方法は?
配列の要素への参照を考えるindex = element_pointer - &vector[0];
、これはあまりにも錆に可能なはずです。
ベクトル要素からメモリアドレスを取得する能力がありますが、usize
に変換してから、それらを減算します.Rustでこれを行うにはもっと便利で便利ですか?
だから、人々がポインタやものを持ってきた問題を考えると、これを行うための私見最善の方法は、次のとおりです。
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
sがすること、あらゆるタイプのため、この方法を使用することができますが[T]
私は一般に 'index_of_unchecked'に' debug_assert'をお勧めします。 – ubsan
もっと簡単な方法はありません。その理由は、その答えを与える操作やメソッドが、Vec
(またはより可能性の高いスライス)とそのコレクション内の何かでのみ使用できることを保証することは難しいと思います。 Rustはあなたが別のベクトルへの参照でそれを呼び出すことを許可したくありません。
もっと慣用的なことは、まず最初に行う必要がないことです。あなたはVec
に参照を保存することはできません。なぜなら、とにかく寿命のためにVec
から離れたところに非常に永遠にあるので、もしあなたがリファレンスを持っていればインデックスを手に入れることができます。
特に、反復する場合は、enumerate
を使用して、(index, &item)
のペアを反復処理します。
一般的なケースではEnumerateは問題ありませんが、関数が(特別な場合には)親を取得してからベクトルから参照を削除する必要があることもあります。インデックスを通すことは可能ですが、不便です。 – ideasman42
これは、[[&str'の間のバイトオフセットを取得する方法](https://stackoverflow.com/questions/38268529/how-to-get-the-byte-offset-between-str) *答えは "単に' usize'に変換されました。 – mcarton