Sprache

MethodHandles.Loop(MethodHandle[][]) Methode

Definition

Erstellt ein Methodenhandle, das eine Schleife mit mehreren Schleifenvariablen darstellt, die bei jeder Iteration aktualisiert und überprüft werden.

[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

Parameter

clauses
MethodHandle[][]

array of arrays (4-tuples) of MethodHandles adhering to the rules described above.

Gibt zurück

eine Methode behandelt das Verhalten der Schleifen, wie durch die Argumente definiert.

Attribute

Hinweise

Erstellt ein Methodenhandle, das eine Schleife mit mehreren Schleifenvariablen darstellt, die bei jeder Iteration aktualisiert und überprüft werden. Nach Beendigung der Schleife aufgrund eines der Prädikate wird ein entsprechender Finalizer ausgeführt und liefert das Ergebnis der Schleife, die den Rückgabewert des resultierenden Handles darstellt.

Intuitiv wird jede Schleife durch eine oder mehrere "Klauseln" gebildet, die jeweils eine lokale <Em-Iterationsvariable></em> und/oder einen Schleifenausgang angeben. Jede Iteration der Schleife führt jede Klausel in der reihenfolge aus. Eine Klausel kann optional die Iterationsvariable aktualisieren; sie kann optional auch einen Test und einen bedingten Schleifenausgang durchführen. Um diese Logik in Bezug auf Methodenhandles auszudrücken, gibt jede Klausel bis zu vier unabhängige Aktionen:ul>li em init:<</em> An, bevor die Schleife ausgeführt wird, die Initialisierung einer Iterationsvariable v vom Typ V.>><< <li><em>step:</em> When a clause executes, an update step for the iteration variable v. <li><em>pred:</em> When a clause executes, a predicate execution to test for loop exit. <li><em>fini:</em> If a clause causes a loop exit, a finalizer execution to compute the loop's return value. </ul> Die vollständige Abfolge aller Iterationsvariablentypen in Klauselreihenfolge wird nicht als (V...). Die Werte selbst sind (v...). Wenn wir von "Parameterlisten" sprechen, beziehen wir uns in der Regel auf Typen, aber in einigen Kontexten (beschreibende Ausführung) sind die Listen tatsächliche Werte.

Einige dieser Klauselnteile werden möglicherweise gemäß bestimmten Regeln weggelassen, und in diesem Fall wird ein nützliches Standardverhalten bereitgestellt. Eine ausführliche Beschreibung finden Sie unten.

<em>Parameters optional überall:</em> Each clause function is allowed but not required to accept a parameter for each iteration variable v. Ausnahme: Die Init-Funktionen können keine v Parameter annehmen, da diese Werte noch nicht berechnet werden, wenn die Init-Funktionen ausgeführt werden. Jede Klauselfunktion kann jede nachfolgende Unterteilung von Parametern, die er übernehmen kann, vernachlässigen. Tatsächlich kann jede Klauselnfunktion überhaupt keine Argumente annehmen.

<em>Loop parameters:</em> A clause function may take all the iteration variable values it is recht to, in which case it may also take more trailing parameters. Solche zusätzlichen Werte werden als Em-Schleifenparameter></em> bezeichnet<, wobei ihre Typen und Werte als (A...) und (a...). Diese werden zu den Parametern des resultierenden Schleifenziehpunkts, der bei jeder Ausführung der Schleife bereitgestellt werden soll. (Da init-Funktionen Iterationsvariablen vnicht akzeptieren, ist jeder Parameter für eine Init-Funktion automatisch ein Schleifenparameter a.) Wie bei Iterationsvariablen sind Klauselfunktionen zulässig, aber nicht erforderlich, um Schleifenparameter zu akzeptieren. Diese Schleifenparameter dienen als loop-invariant-Werte, die in der gesamten Schleife sichtbar sind.

<em>Parameters visible everywhere:</em> Each non-init clause function is permitted to observ the entire loop state, because it can be passed the full list (v... a...) of current iteration variable values and incoming loop parameters. Die Init-Funktionen können den anfänglichen Präschleifenzustand im Formular (a...)beobachten. Die meisten Klauselnfunktionen benötigen nicht alle diese Informationen, aber sie werden formell damit verbunden sein, als wäre dies der #dropArgumentsFall. "astar"> Genauer gesagt, verwenden wir die Notation (V*) , um ein beliebiges Präfix einer vollständigen Sequenz (V...) (und ebenso für (v*), (A*)) (a*)auszudrücken. In dieser Schreibweise ist (A*)die allgemeine Form einer Init-Funktionsparameterliste , und die allgemeine Form einer Nicht-Init-Funktionsparameterliste ist (V*) oder (V... A*).

<em>Checking clause structure:</em> Given a set of clauses, there is a number of checks and adjustments perform to connect all the parts of the loop. Sie werden in den nachstehenden Schritten ausführlich beschrieben. In diesen Schritten entspricht jedes Vorkommen des Worts "must" einem Ort, an IllegalArgumentException dem die erforderliche Einschränkung nicht von den Eingaben des Schleifenkombinators erfüllt wird.

<em>Effektiv identische Sequenzen:</em> "effid"> Eine Parameterliste A ist definiert, um effektiv identisch</em> mit einer anderen Parameterliste B zu sein<>, wenn A sie B identisch sind oder A kürzer und mit einem richtigen Präfix Bidentisch ist. Wenn wir von einer nicht angeordneten Gruppe von Parameterlisten sprechen, sagen wir, dass die Gruppe "effektiv identisch" als Ganzes ist, wenn der Satz eine längste Liste enthält, und alle Mitglieder des Satzes effektiv mit dieser längsten Liste identisch sind. Beispielsweise ist jeder Satz von Typsequenzen des Formulars (V*) effektiv identisch, und dasselbe gilt, wenn weitere Sequenzen des Formulars (V... A*) hinzugefügt werden.

<em>Schritt 0: Bestimmen der Klauselstruktur.</em><ol type="a"><li>The clause array (of type MethodHandle[][]) must be non-null and contain at least one element. <li>Das Klauselarray darf keine Unterarrays enthalten, die länger als vier Elemente sind null. <Li-Klauseln>, die kürzer als vier Elemente sind, werden behandelt, als ob sie von null Elementen auf Länge 4 aufgefüllt wurden. Der Abstand erfolgt durch Anfügen von Elementen an das Array. <li-Klauseln>mit allen nulls werden ignoriert. <li>Each clause is treated as a four-tuple of functions, called "init", "step", "pred" and "fini". </ol>

<em>Schritt 1A: Bestimmen sie Iterationsvariablentypen (V...).</em><ol type="a"><li>Der Iterationsvariablentyp für jede Klausel wird mithilfe der Init- und Schrittrücklauftypen der Klausel bestimmt. <li>Wenn beide Funktionen nicht angegeben werden, gibt es keine Iterationsvariable für die entsprechende Klausel (void wird als Typ verwendet, um anzugeben, dass). Wenn einer von ihnen ausgelassen wird, definiert der Rückgabetyp des anderen den Iterationsvariablentyp der Klausel. Wenn beide angegeben sind, definiert der allgemeine Rückgabetyp (sie müssen identisch sein) den Iterationsvariablentyp der Klausel. <li>Form the list of return types (in clause order), omitting all occurrences of void. <li>Diese Liste der Typen wird als "Iterationsvariablentypen" ((V...)) bezeichnet. </ol>

<em>Step 1B: Determine loop parameters (A...).</em><ul><li>Untersuchen und Sammeln von Init-Funktionsparameterlisten (die des Formulars (A*)sind). <li>Untersuchen und sammeln Sie die Suffixe der Schritt-, Präd- und fini-Parameterlisten nach dem Entfernen der Iterationsvariablentypen. (Sie müssen über die Form (V... A*)verfügen; nur teile (A*) sammeln.) <li>Sammeln Sie keine Suffixe aus Schritt-, Präd- und fini-Parameterlisten, die nicht mit allen Iterationsvariablentypen beginnen. (Diese Typen werden in Schritt 2 zusammen mit allen Klauselfunktionstypen überprüft.) <li>Ausgelassene Klauselfunktionen werden ignoriert. (Entsprechend gelten sie als leere Parameterlisten.) <li>Alle gesammelten Parameterlisten müssen effektiv identisch sein. <li>Die längste Parameterliste (die unbedingt eindeutig ist) wird als "externe Parameterliste" ((A...)) bezeichnet. <li>Wenn keine solche Parameterliste vorhanden ist, wird die Externe Parameterliste als leere Sequenz verwendet. <li>Die kombinierte Liste, die aus Iterationsvariablentypen besteht, gefolgt von den externen Parametertypen, wird als "interne Parameterliste" bezeichnet. </ul>

<em>Schritt 1C: Ermitteln des Rückgabetyps der Schleife.</em><ol type="a"><li>Examine fini function return types, ignorieren ausgelassene fini-Funktionen. <li>Wenn keine fini-Funktionen vorhanden sind, lautet voidder Rückgabetyp der Schleife. <li>Andernfalls definiert der allgemeine Rückgabetyp R der fini-Funktionen (ihre Rückgabetypen müssen identisch sein) den Rückgabetyp der Schleife. </ol>

<em>Schritt 1D: Überprüfen anderer Typen.</em><ol type="a"><li>There must be at least one non-omitted pred function. <li>Jede nicht ausgelassene prädierte Funktion muss einen boolean Rückgabetyp aufweisen. </ol>

<em>Schritt 2: Bestimmen von Parameterlisten.</em><ol type="a"><li>Die Parameterliste für das resultierende Schleifenhandle ist die externe Parameterliste (A...). <li>Die Parameterliste für init-Funktionen wird an die externe Parameterliste angepasst. (Beachten Sie, dass ihre Parameterlisten bereits effektiv mit dieser Liste identisch sind.) <li>Die Parameterliste für jede nicht ausgelassene, nicht init -Funktion (Schritt, Präd und fini) muss effektiv mit der internen Parameterliste (V... A...)identisch sein. </ol>

<em>Schritt 3: Ausfüllen ausgelassener Funktionen.</em><ol type="a"><li>Wenn eine Init-Funktion weggelassen wird, verwenden Sie einen #empty Standardwert für den Iterationsvariablentyp der Klausel. <li>Wenn eine Schrittfunktion nicht angegeben wird, verwenden Sie eine #identity Identitätsfunktion des Iterationsvariablentyps der Klausel; fügen Sie abgelegte Argumentparameter vor dem Identitätsfunktionsparameter für die Nicht-Iterationsvariablenvoid der vorherigen Klauseln ein. (Dadurch wird die Schleifenvariable in eine lokale Schleife umgewandelt.) <li>Wenn eine prädierte Funktion nicht angegeben wird, verwenden Sie eine Konstante.If a pred function is omitted, use a constant true function. (Dies wird die Schleife beibehalten, soweit es sich um diese Klausel handelt. Beachten Sie, dass in solchen Fällen die entsprechende fini-Funktion nicht erreichbar ist.) <li>Wenn eine fini-Funktion nicht angegeben wird, verwenden Sie einen #empty Standardwert für den Rückgabetyp der Schleife. </ol>

<em>Schritt 4: Füllen Sie fehlende Parametertypen aus.</em><ol type="a"><li>An diesem Punkt ist jede Init-Funktionsparameterliste effektiv mit der externen Parameterliste (A...)identisch, aber einige Listen sind möglicherweise kürzer. Für jede Init-Funktion mit einer kurzen Parameterliste füllen Sie das Ende der Liste aus. <li>An diesem Punkt ist jede Nicht-Init-Funktionsparameterliste effektiv mit der internen Parameterliste (V... A...)identisch, aber einige Listen können kürzer sein. Für jede Nicht-Init-Funktion mit einer kurzen Parameterliste füllen Sie das Ende der Liste aus. <li>Argumentlisten werden durch #dropArgumentsToMatch(MethodHandle, int, List, int) aufgefüllt, wobei nicht verwendete nachfolgende Argumente gelöscht werden. </ol>

<em>Schlussbeobachtungen.</em><ol type="a"><li>Nach diesen Schritten wurden alle Klauseln durch Angabe von ausgelassenen Funktionen und Argumenten angepasst. <li>All init functions have a common parameter type list (A...), which the final loop handle will also have. <li>All fini functions have a common return type R, which the final loop handle will also have. <li>Alle Nicht-Init-Funktionen verfügen über eine allgemeine Parametertypliste (V... A...)mit (nicht-void) Iterationsvariablen V gefolgt von Schleifenparametern. <li>Jedes Paar von Init- und Schrittfunktionen stimmt in ihrem Rückgabetyp Vüberein. <li>Jede Nicht-Init-Funktion kann die aktuellen Werte (v...) aller Iterationsvariablen beobachten. <li>Jede Funktion kann die eingehenden Werte (a...) aller Schleifenparameter beobachten. </ol>

<em-Beispiel>.</em> Als Folge von Schritt 1A hat der loop Kombinator die folgende Eigenschaft: <ul><li>Given N clauses Cn = {null, Sn, Pn} mit n = 1..N. <li>Angenommen, Prädikathandles Pn sind entweder null oder haben keine Parameter. (Nur eine Pn muss nicht seinnull.) <li>Angenommen, Schritthandles Sn weisen Signaturen für einige Konstanten (B1..BX)RnX>=Nauf. <li>angenommen Q , ist die Anzahl nicht ungültiger Typen Rnund (V1...VQ) die Abfolge dieser Typen. <li>Es muss sein, Vn == Bn für n = 1..min(X,Q). <li>Die Parametertypen Vn werden als loop-local state-Elemente (V...)interpretiert. <li>Any remaining types BQ+1..BX (if Q<X) will determine the result loop handle's parameter types (A...). </ul> In diesem Beispiel wurden die Parameter (A...) des Schleifenziehpunkts von den Schrittfunktionen abgeleitet, was natürlich ist, wenn der Großteil der Schleifenberechnung in den Schritten erfolgt. Bei einigen Schleifen kann die Belastung der Berechnung in den prädierten Funktionen am stärksten sein, und daher müssen die prädierten Funktionen möglicherweise die Parameterwerte der Schleife akzeptieren. Bei Schleifen mit komplexer Ausgangslogik müssen die fini-Funktionen möglicherweise Schleifenparameter akzeptieren und ebenso für Schleifen mit komplexer Einstiegslogik, bei denen die Init-Funktionen die zusätzlichen Parameter benötigen. Aus solchen Gründen sind die Regeln für die Bestimmung dieser Parameter so symmetrisch wie möglich, über alle Klauselnteile hinweg. Im Allgemeinen funktionieren die Schleifenparameter als allgemeine invariante Werte in der gesamten Schleife, während die Iterationsvariablen als allgemeine Variantenwerte funktionieren oder (wenn keine Schrittfunktion vorhanden ist) als interne Schleife invarianten Temporärdateien.

<em>Loop-Ausführung.</em><ol type="a"><li>When the loop is called, the loop input values are saved in locals, to be passed to each clause function. Diese Locals sind Schleife invariant. <li>Each init function is executed in clause order (passing the external arguments (a...)) and the non-valuesvoid are saved (as the iteration variables (v...)) into locals. Diese Gebietsschemas sind Schleife unterschiedlich (es sei denn, ihre Schritte verhalten sich als Identitätsfunktionen, wie oben erwähnt). <li>Alle Funktionsausführungen (außer init-Funktionen) werden an die interne Parameterliste übergeben, bestehend aus den Nicht-Iterationswerten (v...)void (in Klauselreihenfolge) und dann den Schleifeneingaben (a...) (in Argumentreihenfolge). <li>Der Schritt und die vordefinierten Funktionen werden dann in Klauselreihenfolge (Schritt vor vor dem Voraus) ausgeführt, bis eine vorkonfigurierte Funktion zurückgegeben wird false. <li>Das Nicht-Ergebnisvoid eines Schritt-Funktionsaufrufs wird verwendet, um den entsprechenden Wert in der Sequenz (v...) von Schleifenvariablen zu aktualisieren. Der aktualisierte Wert ist sofort für alle nachfolgenden Funktionsaufrufe sichtbar. <li>Wenn eine pred-Funktion zurückgibt false, wird die entsprechende fini-Funktion aufgerufen, und der resultierende Wert (vom Typ R) wird von der Schleife als Ganzes zurückgegeben. <li>Wenn alle vordefinierten Funktionen immer "true" zurückgeben, wird nie eine fini-Funktion aufgerufen, und die Schleife kann nicht beendet werden, außer durch Auslösen einer Ausnahme. </ol>

<em>Nutzungstipps.</em><ul><li>Obwohl jede Schrittfunktion die aktuellen Werte von <em>all</em> der Schleifenvariablen empfängt, muss eine Schrittfunktion manchmal nur den aktuellen Wert ihrer eigenen Variablen beobachten. In diesem Fall muss die Schrittfunktion möglicherweise explizit #dropArguments alle vorherigen Schleifenvariablen ablegen. Dies erfordert, dass ihre Typen in einem Ausdruck wie dropArguments(step, 0, V0.class, ...). <Li>Loop-Variablen müssen nicht variieren; sie können Schleife invariant sein. Eine Klausel kann eine Schleife invariant durch eine geeignete Init-Funktion ohne Schritt-, Präd- oder Fini-Funktion erstellen. Dies kann hilfreich sein, um ein Eingehendes Schleifenargument in die Schritt- oder Pred-Funktion einer angrenzenden Schleifenvariable zu verkabeln. <li>Wenn einige der Klauselnfunktionen virtuelle Methoden für eine Instanz sind, kann die Instanz selbst bequem in eine anfängliche invariante Schleife "Variable" platziert werden, wobei eine anfängliche Klausel wie new MethodHandle[]{identity(ObjType.class)}verwendet wird. In diesem Fall ist der Instanzverweis der erste Iterationsvariablenwert, und es ist einfach, virtuelle Methoden als Klauselnteile zu verwenden, da alle einen führenden Instanzverweis verwenden, der mit diesem Wert übereinstimmt. </ul>

Hier ist pseudocode für den resultierenden Schleifenziehpunkt. Wie oben dargestellt, und v stellen Sie die Typen und Werte von Schleifenvariablen dar; A und a stellen Argumente dar, V die an die gesamte Schleife übergeben werden; und R ist der allgemeine Ergebnistyp aller Finalizer sowie der resultierenden Schleife. <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> Note that the parameter type lists (V...) and (A...) been expanded to their full length, even though individual clause functions may neglect to take them all. Wie oben erwähnt, werden fehlende Parameter wie von #dropArgumentsToMatch(MethodHandle, int, List, int).

Hinzugefügt in 9.

Java Dokumentation für java.lang.invoke.MethodHandles.loop(java.lang.invoke.MethodHandle[]...).

Teile dieser Seite sind Änderungen auf der Grundlage von Arbeiten, die von der Android Open Source Project erstellt und gemeinsam verwendet und gemäß den in der 2.5 Attribution License beschriebenen Begriffen verwendet werden.

Gilt für: