Language

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[][]

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

返品

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

属性

注釈

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

直感的に、すべてのループは 1 つ以上の "句" で形成され、それぞれがローカルの <em>iteration 変数</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>Loop parameters:</em> A 句関数は、受け取る権利のあるすべての反復変数値を受け取ることができます。その場合は、後続のパラメーターをさらに受け取ることもできます。 このような追加の値は、 <em>loop パラメーター</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 句構造体:</em> 一連の句を指定すると、ループのすべての部分を接続するために多数のチェックと調整が実行されます。 以下の手順で詳しく説明します。 これらの手順では、"must" という単語が出現するたびに、ループ結合子への入力によって必要な制約が満たされていない場合に IllegalArgumentException がスローされる場所に対応します。

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

<em>Step 0: 句の構造を決定します。</em><ol type="a"><li>句配列 ( MethodHandle[][] 型) はnull 以外で、少なくとも 1 つの要素を含む必要があります。 <li>句配列には、 nullまたはサブ配列が 4 つの要素より長い場合があります。 <li>4 要素より短い値は、長さ 4 の要素 null 埋め込まれたかのように扱われます。 パディングは、配列に要素を追加することによって行われます。 <li>すべての nullを無視します。 <li>Each 句は、"init"、"step"、"pred"、および "fini" という 4 組の関数として扱われます。 </ol>

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

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

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

<em>Step 1D: 他の型を確認します。</em><ol type="a"><li>省略されていない pred 関数を少なくとも 1 つ指定する必要があります。 <li>省略されていない pred 関数には、 boolean 戻り値の型が必要です。 </ol>

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

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

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

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

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

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

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

結果のループ ハンドルの擬似コードを次に示します。 上記のように、 V と v はループ変数の型と値を表します。 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ドキュメント。

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

適用対象