Язык

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при соблюдении правил, описанных выше.

Возвращаемое значение

дескриптор метода, который представляет поведение циклирования, как определено аргументами.

Атрибуты

Комментарии

Создает дескриптор метода, представляющий цикл с несколькими переменными цикла, которые обновляются и проверяются при каждой итерации. После завершения цикла из-за одного из предикатов соответствующий метод завершения выполняется и предоставляет результат цикла, который является возвращаемым значением результирующего дескриптора.

Интуитивно каждый цикл формируется одним или несколькими предложениями, каждый из которых задает локальную <>переменную< итерации итерации или> выход цикла. Каждая итерация цикла выполняет каждое предложение по порядку. Предложение может при необходимости обновить переменную итерации; При необходимости он может выполнять тестовый и условный выход из цикла. Чтобы выразить эту логику с точки зрения дескрипторов методов, каждое предложение будет указывать до четырех независимых действий: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 необязательный везде:</em> Каждая функция предложения разрешена, но не требуется принимать параметр для каждой переменной vитерации. В качестве исключения функции инициализации не могут принимать какие-либо v параметры, так как эти значения еще не вычисляются при выполнении функций инициализации. Любая функция предложения может игнорировать любые конечные вложенные значения параметров, которые он имеет право принимать. На самом деле любая функция предложения не может принимать никаких аргументов вообще.

< >Параметры em Loop:</em> A функция предложения может принимать все значения переменных итерации, которыми он имеет право, в этом случае может также потребоваться больше конечных параметров. Такие дополнительные значения называются <параметрами< цикла em>/em>, а их типы и значения нотированы как (A...) и (a...). Они становятся параметрами результирующего дескриптора цикла, который будет предоставляться при выполнении цикла. (Так как функции инициации не принимают переменные vитерации, любой параметр функции init автоматически является параметром aцикла.) Как и в случае с переменными итерации, функции предложения разрешены, но не требуются для принятия параметров цикла. Эти параметры цикла действуют как инвариантные значения цикла, видимые во всем цикле.

< >Em Параметры, видимые везде:</em> Каждая функция предложения, отличного от инициализации, разрешена наблюдать за состоянием всего цикла, так как его можно передать полный список (v... a...) текущих значений переменных итерации и входящих параметров цикла. Функции инициализации могут наблюдать начальное состояние предварительного цикла в форме (a...). Большинству функций предложения не потребуется все эти сведения, но они будут официально подключены к нему, как если бы.#dropArguments "astar"> Более конкретно, мы будем использовать нотацию (V*) для выражения произвольного префикса полной последовательности (V...) (и аналогично для (v*), (A*)). (a*) В этой нотации общая форма списка параметров функции инициализации, (A*)а также общая форма списка параметров функции, отличного от инициализации, или (V*)(V... A*).

<Структура предложения em>Checking:</em> С учетом набора предложений существует ряд проверок и корректировки, выполняемых для подключения всех частей цикла. Они подробно описаны в приведенных ниже шагах. В этих шагах каждое вхождение слова "должно" соответствовать месту, где IllegalArgumentException будет возникать, если необходимое ограничение не соответствует входным данным комбинатору цикла.

<Em>Фактически идентичные последовательности:</em> "effid"> Список A параметров определяется как>< эм фактически идентичный</em> другому списку B параметров, если A и B совпадают, или A если короче и совпадает с соответствующим префиксомB. Если говорить о неупорядоченном наборе списков параметров, мы говорим, что набор "фактически идентичен" в целом, если набор содержит самый длинный список, и все члены набора фактически идентичны тому самому длинному списку. Например, любой набор последовательностей типов формы (V*) фактически идентичен, и то же самое верно, если добавляются дополнительные последовательности формы (V... A*) .

< >Шаг 0. Определение структуры предложения.</em><ol type="a"><li>Массив предложений (типаMethodHandle[][]) должен быть не-null и содержать хотя бы один элемент. <li>Массив предложений не может содержать nullмассивы s или вложенных массивов до четырех элементов. <Предложения li>короче четырех элементов обрабатываются так, как если бы они были заполнены null элементами до длины четыре. Заполнение выполняется путем добавления элементов в массив. <предложения li>со всеми nulls игнорируются. <li>Каждое предложение рассматривается как четырех кортеж функций, называемых "init", "step", "pred" и "fini". </ol>

< >Шаг 1A. Определение типов (V...)переменных итерации.</em><ol type="a"><li>Тип переменной итерации для каждого предложения определяется с помощью инициализации предложения и типов возвращаемых шагов. <li>, если обе функции опущены, переменная итерации для соответствующего предложения отсутствует (void используется в качестве типа для указания этого). Если один из них опущен, возвращаемый тип другого определяет тип переменной итерации предложения. Если оба значения заданы, общий тип возвращаемого значения (они должны быть идентичными) определяет тип переменной итерации предложения. <li>Форма списка возвращаемых типов (в порядке предложения), опустив все вхождения void. <li>Этот список типов называется "типами переменных итерации" ((V...)). </ol>

< >Шаг 1B. Определение параметров (A...)цикла.</em><ul><li>Проверьте и соберите списки параметров функции инициализации (которые относятся к форме(A*)). <li>Проверьте и соберите суффиксы шагов, предопределенных и fini параметров, после удаления типов переменных итерации. (Они должны иметь форму (V... A*); сбор только (A*) частей.) <li>Не собирать суффиксы из шага, предустановки и списки параметров fini, которые не начинаются со всех типов переменных итерации. (Эти типы будут проверены на шаге 2 вместе со всеми типами функций предложения.) <li>Пропущенные функции предложения игнорируются. (Аналогично, они считаются пустыми списками параметров.) <li>Все собранные списки параметров должны быть фактически идентичными. <li>Самый длинный список параметров (который обязательно уникальный) называется "внешним списком параметров" ((A...)). <li>Если такого списка параметров нет, внешний список параметров принимается для пустой последовательности. <li>Объединенный список, состоящий из типов переменных итерации, за которым следуют внешние типы параметров, называются внутренним списком параметров. </ul>

< >Шаг 1C. Определение типа возвращаемого цикла.</em><ol type="a"><li>Проверьте типы возвращаемых функций fini, игнорируя пропущенные функции fini. <li>Если нет функций fini, тип возвращаемого цикла имеет значение void. <li>В противном случае общий тип R возвращаемых функций fini (их возвращаемые типы должны быть идентичными) определяет тип возвращаемого цикла. </ol>

< >Шаг 1D. Проверьте другие типы.</em><ol type="a"><li>Есть по крайней мере одна неопустимая функция. <li>Каждая неопустимая функция должна иметь тип возвращаемого boolean значения. </ol>

< >Шаг 2. Определение списков параметров.</em><ol type="a"><li>Список параметров для результирующего дескриптора цикла будет внешним списком (A...)параметров. <li>Список параметров для функций инициализации будет изменен на внешний список параметров. (Обратите внимание, что их списки параметров уже фактически идентичны этому списку.) <li>Список параметров для каждой функции, отличной от опущенной, неинициализации (шаг, предварительной и fini) должен быть фактически идентичен внутреннему списку (V... A...)параметров. </ol>

< >Шаг 3. Заполнение опущенных функций.</em><ol type="a"><li>Если функция init опущена, используйте значение по умолчанию #empty по умолчанию для типа переменной итерации предложения. <li>, если функция шага опущена, используйте функцию удостоверения #identity типа итерации предложения; вставьте удаленные параметры аргумента перед параметром функции идентификации для переменных неитерацииvoid предыдущих предложений. (Это приведет к тому, что переменная цикла превращается в локальный инвариантный цикл.) <li>Если предопределенная функция опущена, используйте константную true функцию. (Это будет продолжать цикл, так как это предложение обеспокоено. Обратите внимание, что в таких случаях соответствующая функция fini недоступна.) <li>Если функция fini опущена, используйте значение по умолчанию #empty для возвращаемого типа цикла. </ol>

< >Шаг 4. Заполнение отсутствующих типов параметров.</em><ol type="a"><li>На этом этапе каждый список параметров функции инициализации фактически идентичен внешнему списку (A...)параметров, но некоторые списки могут быть короче. Для каждой функции инициализации со списком коротких параметров заведите конец списка. <li>На этом этапе каждый список параметров функции без инициализации фактически идентичен внутреннему списку (V... A...)параметров, но некоторые списки могут быть короче. Для каждой функции, отличной от инициализации с коротким списком параметров, заведите конец списка. <списки аргументов li>заполняются #dropArgumentsToMatch(MethodHandle, int, List, int) удаляет неиспользуемые конечные аргументы. </ol>

<Em>Окончательные наблюдения.</em><ol type="a"><li>После этих шагов все предложения были скорректированы путем предоставления опущенных функций и аргументов. <li>Все функции инициализации имеют общий список (A...)типов параметров, который также будет иметь конечный дескриптор цикла. <li>Все функции fini имеют общий тип возвращаемого значения R, который также будет иметь конечный дескриптор цикла. <li>Все функции, отличныеvoid от инициализации, имеют общий список (V... A...)типов параметров, из переменных V итерации , за которыми следует параметры цикла. <li>Каждая пара функций инициализации и шагов согласуется в их возвращаемом типе V. <li>Каждая неинициативная функция сможет наблюдать текущие значения (v...) всех переменных итерации. <li>Каждая функция сможет наблюдать входящие значения (a...) всех параметров цикла. </ol>

<Пример em>.</em> В результате шага 1A выше loop комбинатор имеет следующее свойство: <ul><li>given N clauses Cn = {null, Sn, Pn} with n = 1..N. <li>Предположим, дескриптор Pn предиката либо null не имеет параметров. (Только один Pn должен быть не-null.) <li>Предположим, что дескриптор Sn шага содержит сигнатуры для некоторых (B1..BX)Rnконстант X>=N. <li>Предположим Q , является числом типов Rn, непустых и (V1...VQ) является последовательностью этих типов. <li>Должно быть, что Vn == Bn для n = 1..min(X,Q). <li>Типы Vn параметров интерпретируются как элементы состояния цикла с локальным состоянием (V...). <li>Любые остальные типы (еслиQ<X) определяют типы BQ+1..BX(A...)параметров результирующего обработчика цикла. </ul> В этом примере параметры (A...) дескриптора цикла были производными от функций шага, что естественно, если большинство вычислений цикла происходит в шагах. Для некоторых циклов бремя вычислений может быть самым тяжелым в предопределенных функциях, поэтому предустановленные функции могут принимать значения параметров цикла. Для циклов с сложной логикой выхода функции fini могут потребоваться принять параметры цикла, а также для циклов с сложной логикой входа, где функции инициализации потребуют дополнительных параметров. По таким причинам правила определения этих параметров являются симметричными, как это возможно, во всех частях предложения. Как правило, параметры цикла выполняются как общие инвариантные значения во всем цикле, а переменные итерации выполняются в качестве общих значений вариантов или (если нет функции шага) в качестве внутренних инвариантных временных циклов.

<Выполнение цикла em>.</em><ol type="a"><li>При вызове цикла входные значения цикла сохраняются в локальных стандартах, которые передаются каждой функции предложения. Эти локальные параметры являются инвариантными. <li>Каждая функция инициализации выполняется в порядке предложения (передавая внешние аргументы (a...)) и не-void значения сохраняются (как переменные (v...)итерации) в локальные. Эти локальные жители будут циклически разными (если их действия не ведут себя как функции идентификации, как отмечалось выше). <li>Все выполнения функций (за исключением функций init) будут переданы внутренний список параметров, состоящий из значений (v...) , отличныхvoid от итерации (в порядке предложения), а затем входных данных цикла (в порядке аргумента (a...) ). <li>Шаг и предустановленные функции затем выполняются в порядке предложения (шаг перед предварительной), пока предопределенная функция не возвращается 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>не требуются для разных значений; они могут быть инвариантными. Предложение может создать инвариантный цикл с помощью подходящей функции инициализации без шага, предустановки или функции fini. Это может быть полезно для "провода" входящего аргумента цикла в шаг или предопределенную функцию соседней переменной цикла. <li>Если некоторые функции предложения являются виртуальными методами экземпляра, сам экземпляр может быть удобно помещен в начальный инвариантный цикл "переменная", используя начальное предложение, например new MethodHandle[]{identity(ObjType.class)}. В этом случае ссылка на экземпляр будет первым значением переменной итерации и будет легко использовать виртуальные методы в качестве частей предложения, так как все из них будут принимать ссылку на ведущий экземпляр, соответствующий значению. </ul>

Ниже приведен псевдокод для результирующего дескриптора цикла. Как описано выше, и v представляют типы и значения переменных цикла; A и a представляют аргументы, V передаваемые в весь цикл; и 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[]...).

Части этой страницы — это изменения на основе работы, созданной и общей Project и используемых в соответствии с условиями, описанными в разделе "".

Применяется к