MethodHandles.Loop(MethodHandle[][]) メソッド

定義

各反復時に更新およびチェックされる複数のループ変数を持つループを表すメソッド ハンドルを構築します。

[Android.Runtime.Register("loop", "([[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;", "", ApiSince=33)]
public static Java.Lang.Invoke.MethodHandle? Loop (params Java.Lang.Invoke.MethodHandle[][]? clauses);
[<Android.Runtime.Register("loop", "([[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;", "", ApiSince=33)>]
static member Loop : Java.Lang.Invoke.MethodHandle[][] -> Java.Lang.Invoke.MethodHandle

パラメーター

clauses
MethodHandle[][]

上記の規則に従う の配列 (4 タプル) MethodHandleの配列。

戻り値

引数で定義されているループ動作を具体化するメソッド ハンドル。

属性

注釈

各イテレーションで更新およびチェックされる複数のループ変数を持つループを表すメソッド ハンドルを構築します。 述語のいずれかが原因でループが終了すると、対応するファイナライザーが実行され、ループの結果 (結果のハンドルの戻り値) が提供されます。

直感的に、すべてのループは 1 つ以上の "句" で形成され、それぞれがローカル <em 反復変数</em>> またはループ終了を指定します。 ループの各反復では、各句が順番に実行されます。 句は、必要に応じてその反復変数を更新できます。また、必要に応じて、テストと条件付きループの終了を実行することもできます。 メソッド ハンドルの観点からこのロジックを表現するために、各句は最大 4 つの独立したアクションを指定します。ul>li em init:</em> ループが実行される前に、型 Vの反復変数vの初期化が行われます。>><<< <li><em>step:</em> 句が実行されると、反復変数 vの更新ステップが実行されます。 <li><em>pred:</em> 句が実行されると、ループ終了をテストするための述語の実行。 <li><em>fini:</em> 句によってループが終了した場合、ファイナライザーの実行によってループの戻り値が計算されます。 </ul> すべての反復変数型の完全なシーケンス (句順) は として (V...)示されます。 値自体は になります (v...)。 "パラメーター リスト" と言うと、通常は型を参照しますが、一部のコンテキスト (実行を記述) では、リストは実際の値になります。

これらの句の一部は、特定の規則に従って省略できます。この場合、便利な既定の動作が提供されます。 詳細な説明については、以下を参照してください。

<em>Parameters optional everywhere:</em> 各句関数は許可されますが、各反復変数 vのパラメーターを受け入れる必要はありません。 例外として、init 関数は、init 関数の実行時にこれらの値がまだ計算されないため、パラメーターを受け取 v ることができません。 句関数は、受け取る権利があるパラメーターの後続のサブシーケンスを受け取ることを無視する可能性があります。 実際、句関数は引数をまったく受け取らなくなる可能性があります。

<em>ループ パラメーター:</em> A 句関数は、それが受け取る権利のあるすべての反復変数値を受け取ることができます。その場合、より多くの後続パラメーターを受け取る場合もあります。 このような余分な値は em>ループ パラメーター</em> と呼ばれ<、その型と値は と (a...)として(A...)示されます。 これらは、ループが実行されるたびに指定される、結果のループ ハンドルのパラメーターになります。 (init 関数は反復変数 vを受け入れないため、init 関数へのパラメーターは自動的にループ パラメーター aになります)。反復変数と同様に、句関数は許可されますが、ループ パラメーターを受け入れる必要はありません。 これらのループ パラメーターは、ループ全体で表示されるループインバリアント値として機能します。

<すべての場所に表示される em>パラメーター:</em> 現在の反復変数値と受信ループ パラメーターの完全なリスト (v... a...) を渡すことができるため、init 以外の各句関数はループの状態全体を観察できます。 init 関数は、最初のプリループ状態を という形式 (a...)で観察できます。 ほとんどの句関数は、この情報をすべて必要とするわけではありませんが、 のように正式に接続 #dropArgumentsされます。 "astar"> より具体的には、 表記(V*)を使用して、完全なシーケンス(V...)の任意のプレフィックスを表します (同様に 、(v*)(A*)(a*))。 この表記では、init 関数パラメーター リストの一般的な形式は であり (A*)、init 以外の関数パラメーター リストの一般的な形式は (V*) または (V... A*)です。

<em>Checking clause structure:</em> 句のセットを指定すると、ループのすべての部分を接続するために実行されるチェックと調整がいくつかあります。 これらは、以下の手順で詳しく説明されています。 これらの手順では、"must" という単語が出現するたびに、ループ結合子への入力によって必要な制約が満たされない場合にスローされる場所 IllegalArgumentException に対応します。

<em>実質的に同一のシーケンス:</em> "effid"> パラメーター リストAは、 と が同一<の場合AB、または が短く、 が の適切なプレフィックスと同じ場合Aに、他のBパラメーター リストBと実質的に同一/em> として定義<>されます。 順序付けられていないパラメーター リストのセットについて言えば、セットに最も長いリストが含まれており、セットのすべてのメンバーがその最も長いリストと実質的に同じである場合、セットは全体として "実質的に同一" であると言います。 たとえば、フォームの型シーケンスのセットは実質的に同じであり、フォーム(V*)(V... A*)のシーケンスが追加される場合も同じです。

<em>手順 0: 句の構造を決定します。</em><ol type="a"><li>句配列 (型 MethodHandle[][]) は非null で、少なくとも 1 つの要素を含む必要があります。 <li>句配列には、4 つの要素より長い s またはサブ配列が含 nullまれていない場合があります。 <4 つの要素より短い li>句は、長さ 4 の要素によって null 埋め込まれたかのように扱われます。 埋め込みは、配列に要素を追加することによって行われます。 <すべての nullが含まれる li>句は無視されます。 <li>各句は、"init"、"step"、"pred"、および "fini" と呼ばれる関数の 4 タプルとして扱われます。 </Ol>

<em>ステップ 1A: 反復変数の型を決定します (V...)。</em><ol type="a"><li>各句の反復変数型は、句の init と step の戻り値の型を使用して決定されます。 <li>両方の関数を省略した場合、対応する句 (void を示す型として使用されます) の反復変数はありません。 そのうちの 1 つを省略すると、もう一方の戻り値の型によって句の反復変数型が定義されます。 両方を指定すると、共通の戻り値の型 (同一である必要があります) によって句の反復変数型が定義されます。 <li>戻り値の型の一覧を (句の順序で) 形成し、 のすべての出現箇所を省略します void。 <li>この型のリストは、"反復変数型" ((V...)) と呼ばれます。 </Ol>

<em>ステップ 1B: ループ パラメーターを決定します (A...)。</em><ul><li>init 関数パラメーター リスト (形式 (A*)) を調べて収集します。 <li>繰り返し変数の型を削除した後、ステップ、pred、fini パラメーター リストのサフィックスを調べて収集します。 (彼らは フォーム (V... A*)を持っている必要があります。パーツのみを収集します (A*) 。 <li>すべての反復変数型で始まっていない step、pred、fini パラメーター リストからサフィックスを収集しないでください。 (これらの型は、手順 2 で、すべての句関数型と共にチェックされます)。 <李>省略された句関数は無視されます。 (同様に、パラメーター リストが空であると見なされます)。 <李>収集されたすべてのパラメーター リストは、実質的に同一である必要があります。 <li>最長のパラメーター リスト (必ずしも一意) は"外部パラメーター リスト" ((A...)) と呼ばれます。 <li>このようなパラメーター リストがない場合、外部パラメーター リストは空のシーケンスとして取得されます。 <li>反復変数型とそれに続く外部パラメーター型で構成される結合リストは、"内部パラメーター リスト" と呼ばれます。 </ul>

<em>ステップ 1C: ループの戻り値の型を決定します。</em><ol type="a"><li>fini 関数の戻り値の型を調べます。省略された fini 関数は無視されます。 <li>fini 関数がない場合、ループの戻り値の型は です void。 <li>それ以外の場合、fini 関数の共通戻り値の型 R (戻り値の型は同一である必要があります) によってループの戻り値の型が定義されます。 </Ol>

<em>手順 1D: 他の種類を確認します。</em><ol type="a"><li>少なくとも 1 つの省略されていない pred 関数が必要です。 <li>省略されていないプリド関数には、戻り値の型が boolean 必要です。 </Ol>

<em>手順 2: パラメーター リストを決定します。</em><ol type="a"><li>結果のループ ハンドルのパラメーター リストは、外部パラメーター リスト (A...)になります。 <li>init 関数のパラメーター リストは、外部パラメーター リストに合わせて調整されます。 (パラメーター リストは、既にこのリストと実質的に同じであることに注意してください)。 <李>省略されていない、init 以外 (step、pred、fini) 関数のパラメーター リストは、内部パラメーター リスト (V... A...)と実質的に同じである必要があります。 </Ol>

<em>手順 3: 省略した関数を入力します。</em><ol type="a"><li>init 関数を省略した場合は、句の反復変数型に #empty 既定値を使用します。 <li>ステップ関数を省略した場合は、句の反復変数型の #identity ID 関数を使用し、前の句の非void 反復変数の ID 関数パラメーターの前にドロップされた引数パラメーターを挿入します。 (これにより、ループ変数がローカル ループインバリアントに変わります)。 <李>前の関数を省略した場合は、定数 true 関数を使用します。 (これは、この句に関する限り、ループを継続します。このような場合、対応する fini 関数に到達できない点に注意してください)。 <李>fini 関数を省略した場合は、ループの戻り値の型 #empty 既定値を使用します。 </Ol>

<em>手順 4: 不足しているパラメーター型を入力します。</em><ol type="a"><li>この時点では、すべての init 関数パラメーター リストは外部パラメーター リスト (A...)と実質的に同じですが、一部のリストは短くなる可能性があります。 短いパラメーター リストを持つすべての init 関数について、リストの末尾を埋め込みます。 <li>この時点で、init 以外の関数パラメーター リストはすべて内部パラメーター リスト (V... A...)と実質的に同じですが、一部のリストは短くなる可能性があります。 短いパラメーター リストを持つ init 以外のすべての関数について、リストの末尾を埋め込みます。 <li>引数リストは、未使用の末尾の引数を削除 #dropArgumentsToMatch(MethodHandle, int, List, int) によって埋め込まれます。 </Ol>

<em>最終的な観察。</em><ol type="a"><li>これらの手順の後、省略された関数と引数を指定することで、すべての句が調整されました。 <li>すべての init 関数には共通のパラメーター型リスト (A...)があります。これは、最後のループ ハンドルにも含まれます。 <li>すべての fini 関数には共通の戻り値の型 Rがあります。これは、最終的なループ ハンドルにも含まれます。 <li>すべての init 以外の関数には、共通のパラメーター型リスト (V... A...)があり、(非void) 反復変数 V の後にループ パラメーターが続きます。 <li>init 関数と step 関数の各ペアは、戻り値の型で一致します V。 <li>各非初期化関数は、すべての反復変数の現在の値 (v...) を観察できます。 <li>すべての関数は、すべてのループパラメータの受信値 (a...) を観察することができます。 </Ol>

<em>例。</em> 上記の手順 1A の結果として、loop組み合わせ子には ul li>Given NCn = {null, Sn, Pn} と のn = 1..Nプロパティ<><があります。 <li>述語ハンドル Pn がパラメーターを持っていないか、 null またはパラメーターを持っていないとします。 (1 つだけPnが非である必要があります)。null<li>ステップ ハンドルSnには、いくつかの定数 X>=Nに対して (B1..BX)Rnシグネチャ があるとします。 <li>void 以外の型の数であり、(V1...VQ)それらの型RnのシーケンスであるとしますQ。 <li>の場合は であるVn == Bnn = 1..min(X,Q)必要があります。 <li>パラメーター型 Vn は、ループ ローカル状態要素 (V...)として解釈されます。 <li>残りの型 BQ+1..BX (の場合 Q<X) は、結果のループ ハンドルのパラメーター型 (A...)を決定します。 </ul> この例では、ループ ハンドル パラメーター (A...) はステップ関数から派生しました。これは、ほとんどのループ計算がステップで行われる場合は自然です。 一部のループでは、プリド関数では計算の負荷が最も大きいので、プリド関数はループ パラメーター値を受け入れる必要がある場合があります。 複雑な終了ロジックを持つループの場合、fini 関数はループ パラメーターを受け入れる必要があり、同様に複雑なエントリ ロジックを持つループの場合は、init 関数に追加のパラメーターが必要になる場合があります。 このような理由から、これらのパラメーターを決定するための規則は、すべての句部分で可能な限り対称です。 一般に、ループ パラメーターはループ全体で共通の不変値として機能しますが、反復変数は共通のバリアント値として機能し、内部ループ不変一時として (ステップ関数がない場合は) 機能します。

<em>ループ実行。</em><ol type="a"><li>ループが呼び出されると、ループ入力値がローカルに保存され、すべての句関数に渡されます。 これらのローカルはループインバリアントです。 <li>各 init 関数は句順 (外部引数 (a...)を渡す) で実行され、非void 値は (反復変数 (v...)として) ローカルに保存されます。 これらのローカルはループが変化します (前述のように、ステップが ID 関数として動作しない限り)。 <li>すべての関数の実行 (init 関数を除く) には、非void 反復値 (v...) (句順) とループ入力 (a...) (引数順) で構成される内部パラメーター リストが渡されます。 <li>ステップ関数と pred 関数は、プリド関数が を返 falseすまで句順 (前のステップ) で実行されます。 <li>ステップ関数呼び出しの非void 結果は、ループ変数のシーケンス (v...) 内の対応する値を更新するために使用されます。 更新された値は、後続のすべての関数呼び出しにすぐに表示されます。 <li>プリド関数が を返す false場合、対応する fini 関数が呼び出され、結果の値 (型 R) がループ全体から返されます。 <li>すべてのプリド関数が常に true を返す場合、fini 関数は呼び出されることがなく、例外をスローする以外はループを終了できません。 </Ol>

<em>使用に関するヒント。</em><ul><li>各ステップ関数は、ループ変数 em>all</em> の現在の<値を受け取りますが、ステップ関数は独自の変数の現在の値のみを観察する必要がある場合があります。 その場合、ステップ関数は、上記のすべてのループ変数を明示的に #dropArguments ドロップする必要がある場合があります。 これには、 のような dropArguments(step, 0, V0.class, ...)式で、型をメンションする必要があります。 <li>ループ変数は変化する必要はありません。ループインバリアントにすることができます。 句は、ステップ関数、pred 関数、または fini 関数なしで、適切な init 関数によってループインバリアントを作成できます。 これは、受信ループ引数を隣接するループ変数のステップ関数または事前関数に "ワイヤリング" する場合に役立ちます。 <li>句関数の一部がインスタンス上の仮想メソッドである場合、インスタンス自体は、}のような new MethodHandle[]{identity(ObjType.class)初期句を使用して、初期不変ループ "variable" に便利に配置できます。 その場合、インスタンス参照は最初の反復変数値になり、仮想メソッドは句の部分として簡単に使用できます。すべてのメソッドは、その値に一致する先頭のインスタンス参照を受け取るのでです。 </ul>

結果のループ ハンドルの擬似コードを次に示します。 上記と同様に、 Vv ループ変数の型と値を表し、 A ループ a 全体に渡される引数を表します。および R は、すべてのファイナライザーと結果ループの共通の結果型です。 <blockquote>

{@code
            V... init...(A...);
            boolean pred...(V..., A...);
            V... step...(V..., A...);
            R fini...(V..., A...);
            R loop(A... a) {
              V... v... = init...(a...);
              for (;;) {
                for ((v, p, s, f) in (v..., pred..., step..., fini...)) {
                  v = s(v..., a...);
                  if (!p(v..., a...)) {
                    return f(v..., a...);
                  }
                }
              }
            }
            }

</blockquote> パラメーターの型が一覧表示 (V...) され (A...) 、その完全な長さに拡張されていることに注意してください。ただし、個々の句関数がそれらすべてを無視する可能性があります。 上で説明したように、不足しているパラメーターは、 のように #dropArgumentsToMatch(MethodHandle, int, List, int)入力されます。

9 に追加されました。

の Java ドキュメント java.lang.invoke.MethodHandles.loop(java.lang.invoke.MethodHandle[]...)

このページの一部は、によって作成および共有され、に記載されている条件に従って使用される作業に基づく変更です。

適用対象