注:How to get subslicesは近いですが、どちらの制約もありません。どのようにパニックにも安全でもないサブスライスを取得するには?
私はこのシグネチャを持つ関数の可能な最適な実装を探しています:
impl Index<Range<usize>>
と同じ機能を持っていますが、
None
で失敗ケースを交換する代わりに、慌てう
fn sub(slice: &[u8], range: Range<usize>) -> Option<&[u8]>;
。 panic
unsafe
コードしてもよいslice
インタフェースの注意深い調査がにもたらした
- 呼出し機能:
ねじれは、一見異常な制約この関数はべきではないことです私の注意:
split_first
とsplit_at
impl Index<Range<usize>>
split_last
(およびバリアント)as_ptr
とfrom_raw_parts
は、しかし、ほとんどは適していません。
split_at
とIndex<Range<usize>>::index
がパニックすることがありfrom_raw_parts
はとしてsub
を実装するために私を残しunsafe
ある:一見作業O(N)複雑性を有している
fn sub(slice: &[u8], range: Range<usize>) -> Option<&[u8]> { if range.start > range.end { return None; } let length = range.end - range.start; if length > slice.len() { return None; } if length == 0 { return Some(b""); } let mut slice = slice; for _ in 0..range.start { if let Some((_, s)) = slice.split_first() { slice = s; } } for _ in 0..(slice.len() - length) { if let Some((_, s)) = slice.split_last() { slice = s; } } Some(slice) }
。むしろ満足していない。
もっと良い方法がありますか?
これを標準ライブラリに実装すると、 'unsafe'を使用することがほぼ保証されます。どうしてあなたはそれを自分で使うのを躊躇していますか?また、本当にパニックにならないコードと 'パニック 'コールを持つコードの違いはありますか?決して**実行されることはありませんか? – Shepmaster
@Shepmaster: 'panic! 'について:静的に'パニック 'が起こらないことを知っていることと'パニック 'が決して起こらないように動的に(テストスイートで)望んでいることには違いがあります。特に、前者の場合、(たとえテストが不安定であったとしても)コード生成がパニックフックを呼び出さないという保証があります。 '安全でない 'に関しては、これは私が現時点で使用しているものですが、私は標準ライブラリに頼って(おそらく純粋に)、より良いテストができ、自分のコードよりも徹底的に監査されていることを好むでしょう。 –
@Shepmaster:私は、 'split_first'と' split_last'が存在し、 'Option'を返すと、' split_at'がそのトラックに続くことを期待しています。私はここでインターフェイスの矛盾に驚いています。 –