まだ読んでいない場合は、範囲に関するこのチュートリアルを読む必要があります。
範囲が消費される場合と消費されない場合は、そのタイプによって異なります。それが入力範囲であり、順方向範囲ではない場合(たとえば、ある種の入力ストリームであるstd.stdio.byLine
場合は、この一例です)、何らかの形または形式で反復すると、それが消費されます。
//Will consume
auto result = find(inRange, needle);
//Will consume
foreach(e; inRange) {}
順方向範囲であり、参照型の場合、反復処理するたびに消費されますが、呼び出しsave
てコピーを取得できます。コピーを消費しても、元の消費は消費されません(また、元の消費も消費されません)。コピー)。
//Will consume
auto result = find(refRange, needle);
//Will consume
foreach(e; refRange) {}
//Won't consume
auto result = find(refRange.save, needle);
//Won't consume
foreach(e; refRange.save) {}
物事がより興味深いものになるのは、値型(または配列)である前方範囲です。それらは、に関しては他の順方向範囲と同じようsave
に機能しますが、単に関数に渡すか、foreach
暗黙的にそれらを使用するという点で異なりsave
ます。
//Won't consume
auto result = find(valRange, needle);
//Won't consume
foreach(e; valRange) {}
//Won't consume
auto result = find(valRange.save, needle);
//Won't consume
foreach(e; valRange.save) {}
したがって、順方向範囲ではない入力範囲を処理している場合は、関係なく消費されます。また、フォワードレンジを扱っている場合、save
消費されないことを保証したい場合は電話する必要があります。そうでない場合は、消費されるかどうかはタイプによって異なります。
に関してはref
、引数を取る範囲ベースの関数を宣言するとref
、それはコピーされないので、渡された範囲が参照型であるかどうかは関係ありませんが、それはあなたが右辺値を渡すことはできません。これは非常に煩わしいため、ref
実際に元の値を常に変更する必要がない限り、範囲パラメータを使用しないでください(たとえば、元の値を明示的に変更するのではなく、元の値を明示的に変更std.range.popFrontN
するため、ref
コピー)。
順方向範囲を使用した範囲ベースの関数の呼び出しに関しては、値型範囲が適切に機能する可能性が最も高くなります。これは、コードが値型範囲で記述およびテストされ、参照型で常に適切にテストされるとは限らないためです。残念ながら、これにはPhobosの関数が含まれます(ただし、修正される予定です。まだすべてのケースで適切にテストされていません。Phobos関数が参照型の前方範囲で適切に機能しない場合は、報告してください)。したがって、参照型の前方範囲は、常に正常に機能するとは限りません。