<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Илья</title><author><name>Илья</name></author><id>https://teletype.in/atom/ifv93</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/ifv93?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@ifv93?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=ifv93"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/ifv93?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-06-07T05:13:45.919Z</updated><entry><id>ifv93:YWPw-4zz0JM</id><link rel="alternate" type="text/html" href="https://teletype.in/@ifv93/YWPw-4zz0JM?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=ifv93"></link><title>2. Side Effects and Effect Handlers в Jetpack Compose</title><published>2024-10-19T13:46:02.375Z</published><updated>2024-10-19T13:46:02.375Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/72/83/7283c7a2-b860-4262-a431-9db365d18cfd.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/07/a2/07a2f84c-3bae-4897-917d-8f1062ed0059.png&quot;&gt;Обработчики сайд-эффектов - важный механизм в Jetpack Compose. Без них разработчику пришлось бы управлять сложной иерархией коллбеков, состоянием, навигацией и тд. Effect Handler'ы упрощают эти задачи.</summary><content type="html">
  &lt;p id=&quot;EEUR&quot;&gt;Обработчики сайд-эффектов - важный механизм в Jetpack Compose. Без них разработчику пришлось бы управлять сложной иерархией коллбеков, состоянием, навигацией и тд. Effect Handler&amp;#x27;ы упрощают эти задачи.&lt;/p&gt;
  &lt;p id=&quot;T1l8&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;YBiy&quot;&gt;&lt;strong&gt;Что такое сайд эффект в Jetpack Compose?&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;S12f&quot;&gt;В терминологии Jetpack Compose - это нечто изменяющее состояние извне функции. Это может привести к непредсказуемому поведению этой функции, а также проблемам с производительностью приложения. В идеале разработчики хотели бы избегать таких вот эффектов в своем коде. Но избежать их полностью не выйдет. Порой все же разработчики сталкиваются с такого рода задачами. Например: показ всплывающего окна или навигация на другой экран. Такое поведение - это в любом случае сайд-эффекты!&lt;/p&gt;
  &lt;p id=&quot;hnTQ&quot;&gt;Jetpack Compose работает на основе рекомпозиций. Чтобы управлять этими механизмами Compose предоставляет специальные тулзы, которые помогают решать задачи в рамках ЖЦ компонентов.&lt;/p&gt;
  &lt;p id=&quot;ROsy&quot;&gt;&lt;strong&gt;Типы сайд эффектов&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;s8Ie&quot;&gt;
    &lt;li id=&quot;jNCI&quot;&gt;LaunchedEffect&lt;/li&gt;
    &lt;li id=&quot;Op84&quot;&gt;rememberCoroutineScope()&lt;/li&gt;
    &lt;li id=&quot;2kE6&quot;&gt;ProduceState&lt;/li&gt;
    &lt;li id=&quot;qEpC&quot;&gt;rememberUpdateState()&lt;/li&gt;
    &lt;li id=&quot;bJP3&quot;&gt;DisposableEffect&lt;/li&gt;
    &lt;li id=&quot;chhE&quot;&gt;SideEffect&lt;/li&gt;
    &lt;li id=&quot;A4vN&quot;&gt;DerivedStateOf&lt;/li&gt;
    &lt;li id=&quot;9dMg&quot;&gt;SnapshotFlow&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;g0yX&quot;&gt;&lt;/p&gt;
  &lt;ol id=&quot;B5yA&quot;&gt;
    &lt;li id=&quot;7CgH&quot;&gt;&lt;strong&gt; LaunchedEffect&lt;/strong&gt; - в Jetpack Compose служит для выполнения IO операций или тяжелых вычислений. В момент когда Compose заходит в композицию, запускается код прописанный в блоке, обернутый в корутину. Также LaunchedEffect получает на вход ключ. Это может быть Unit или другой тип данных. От этого зависит частота его вызова. Код в блоке триггерится в момент, когда значение ключа меняется. Либо же выполняется единоразово если ключ - Unit&lt;/li&gt;
  &lt;/ol&gt;
  &lt;figure id=&quot;e7Se&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/07/a2/07a2f84c-3bae-4897-917d-8f1062ed0059.png&quot; width=&quot;512&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CnWF&quot;&gt;2. &lt;strong&gt;rememberCoroutineScope&lt;/strong&gt; - создает и управляет скоупом корутины. Скоуп привязан к ЖЦ Composable функции. Этот механизм упрощает управление корутинами и снижает риск утечек памяти&lt;/p&gt;
  &lt;figure id=&quot;kzNT&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ab/db/abdbb355-65a9-4a45-87ef-26a8ef2fdb37.png&quot; width=&quot;436&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;1moM&quot;&gt;3. &lt;strong&gt;ProduceState&lt;/strong&gt; - функция позволяющая создавать State объект обернутый в корутину. Это означает что объект состояния будет обновляться в пределах корутины и его изменения будут отражены на Composable функции использующей его. Producer начинает работать когда produceState заходит в композицию и останавливается когда выходит из нее. Установка одного и того же значения в produceState не вызовет рекомпозицию повторно.&lt;/p&gt;
  &lt;figure id=&quot;xs9X&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4a/57/4a57c5e8-f8c4-4dcf-8c0c-ee7dba873024.png&quot; width=&quot;468&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;RDMT&quot;&gt;4. &lt;strong&gt;rememberUpdateState&lt;/strong&gt; - простыми словами это функция в Jetpack Compose используется для запоминания значения которое может быть обновлено во время композиции Composable. Эта функция полезна для хранения результатов тяжелых и длительных операций, которые вы не хотите пересчитывать заново.&lt;/p&gt;
  &lt;figure id=&quot;3124&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f8/3b/f83b0833-2971-4fe6-a4c5-418d7b962466.png&quot; width=&quot;466&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;7hwi&quot;&gt;5. &lt;strong&gt;DisposableEffect&lt;/strong&gt; - это механизм предоставляемый Jetpack Compose для отслеживания ЖЦ Composable и последующей очистки занятых им ресурсов. Очистка ресурсов происходит в тот момент, когда Composable функция удаляется с экрана. По сути работы аналогичен LaunchedEffect, но дополнительно предоставляет функцию &lt;em&gt;onDispose&lt;/em&gt; для очистки ресурсов.&lt;/p&gt;
  &lt;figure id=&quot;T4L8&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/22/0f/220ffef4-296b-40bf-b655-d310bf75b037.png&quot; width=&quot;535&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;0sqJ&quot;&gt;6. &lt;strong&gt;SideEffect&lt;/strong&gt; - это эффект позволяющий Jetpack Compose менять состояние приложения которые находятся вне скоупа Composable функции. Для примера вы можете использовать SideEffect для обновления Data Store или выполнения HTTP запроса основанного на состоянии.&lt;/p&gt;
  &lt;figure id=&quot;KMY8&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/fa/88/fa88b510-c1d0-4d86-85e6-44dc54ebffba.png&quot; width=&quot;407&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Xo0O&quot;&gt;7. &lt;strong&gt;DerivedStateOf&lt;/strong&gt; - полезен когда есть задача вычислить новый стейт на основании предыдущих состояний, снизив тем самым количество ненужных вычислений. &lt;/p&gt;
  &lt;p id=&quot;fkMw&quot;&gt;&lt;em&gt;Например&lt;/em&gt;: у нас может быть поле ввода пароля, чье значение представлено состояние и состояние принимающее этот пароль и высчитывающее его сложность.&lt;/p&gt;
  &lt;figure id=&quot;IWFU&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/82/1d/821d8e3b-9529-4cb5-988a-7810d327d389.png&quot; width=&quot;483&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;mHqx&quot;&gt;8. &lt;strong&gt;snapshotFlow&lt;/strong&gt; - конвертирует State объект во Flow. Это Flow будет эмитить текущее значение объекта State, каждый раз при его изменении.&lt;/p&gt;
  &lt;figure id=&quot;lYOE&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/07/cd/07cd83c8-5a41-400d-b8d1-04a5423cd79e.png&quot; width=&quot;485&quot; /&gt;
  &lt;/figure&gt;

</content></entry><entry><id>ifv93:u7teaAv-kMw</id><link rel="alternate" type="text/html" href="https://teletype.in/@ifv93/u7teaAv-kMw?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=ifv93"></link><title>Composable функции </title><published>2024-10-13T17:23:32.712Z</published><updated>2024-10-13T17:23:32.712Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/c1/86/c1866ce7-375a-4d20-a51f-b0cd070f7626.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/4f/6a/4f6af8c1-dff2-4674-9e7a-a586c3cf51f3.png&quot;&gt;Знакомство с Jetpack Compose лучше всего начать с Composable функций. Они являются кирпичиками нашего UI и хранятся в древовидной структуре данных. Для того чтобы работать с Jetpack Compose, нужно сформировать Compose mindset.</summary><content type="html">
  &lt;p id=&quot;E9M7&quot;&gt;Знакомство с Jetpack Compose лучше всего начать с Composable функций. Они являются кирпичиками нашего UI и хранятся в древовидной структуре данных. Для того чтобы работать с Jetpack Compose, нужно сформировать Compose mindset.  &lt;/p&gt;
  &lt;p id=&quot;lo0U&quot;&gt;Для того чтобы создать нашу первую Composable функцию, нам нужно добавить аннотацию @Composable. Таким образом любая функция в Kotlin может превратиться в Composable - функцию.&lt;br /&gt;&lt;/p&gt;
  &lt;figure id=&quot;Cive&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4f/6a/4f6af8c1-dff2-4674-9e7a-a586c3cf51f3.png&quot; width=&quot;428&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;WS3F&quot;&gt;@Composable объявленная над Kotlin функцией говорит нашему Compose компилятору - конвертируй эту ноду в UI ноду и зарегистрируй в дереве функций. Стоит учесть момент, что Composable функция ничего не возвращает. Она является Unit функцией. Она получает входные данные и производит отрисовку UI. Ее работа очень похожа на некий side-эффект. &lt;/p&gt;
  &lt;p id=&quot;VuCM&quot;&gt;На языке Compose это называется emitting. Composable функция производит отрисовку во время этапа композиции.&lt;/p&gt;
  &lt;figure id=&quot;cbcS&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f4/96/f496850f-ea4b-4be8-a058-d9b6fcf36703.png&quot; width=&quot;1030&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6hNy&quot;&gt;Главной целью для которой служат такие функции является обновление дерева лежащего в памяти. Это позволяет поддерживать актуальное состояние UI. Функции реагируют на изменения данных и перезапускаются параллельно с ним. Также Composable функции могут читать или записывать состояние из дерева.&lt;/p&gt;
  &lt;p id=&quot;ESTC&quot;&gt;&lt;strong&gt;Свойства Composable функций&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;ZBmv&quot;&gt;Аннотирование функции @Composable аннотацией изменяет тип данной функции. Придает ей новые свойства. Разблокирует возможности библиотеки Compose.&lt;/p&gt;
  &lt;p id=&quot;N8Eu&quot;&gt;Compose runtime ожидает на вход Composable функции. Применяет к ним различные оптимизации. &lt;/p&gt;
  &lt;p id=&quot;ZIWl&quot;&gt;&lt;strong&gt;Например&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;fZtd&quot;&gt;
    &lt;li id=&quot;5dKf&quot;&gt; parallel composition - параллельная композиция&lt;/li&gt;
    &lt;li id=&quot;PwoM&quot;&gt; smart recomposition - умная рекомпозиция&lt;/li&gt;
    &lt;li id=&quot;tkYW&quot;&gt; positional memoization - позиционная мемоизация&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;l8hB&quot;&gt;&lt;strong&gt;Вызов контекста&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;fFQb&quot;&gt;Большинство свойств Compose включены компилятором. C того момента как он стал плагином для Kotlin, он проходит все фазы компиляции и имеет доступ ко всей информации, к которой имеет доступ Kotlin компилятор. Это свойство позволяет перехватывать и трансформировать IR (intermediate representation) всех Composable функций и добавлять к ним дополнительную информацию.&lt;/p&gt;
  &lt;p id=&quot;UtJa&quot;&gt;Одной из главных модификаций является добавление параметра Composer как последнего параметра к каждой функции. Его инстанс инжектится в функции в рантайме и прокидывается дочерним функциям в дереве.&lt;/p&gt;
  &lt;figure id=&quot;LWzo&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0a/5e/0a5e792f-6ba0-4d00-8716-e74693eef0ac.png&quot; width=&quot;1076&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;dAjB&quot;&gt;Как мы можем видеть Composer прокинут во всех вызовы в пределах дерева. У Compose есть строгое правило&lt;/p&gt;
  &lt;blockquote id=&quot;fTTF&quot;&gt;Composable функции могут вызываться только из других Composable функций&lt;/blockquote&gt;
  &lt;p id=&quot;1XyE&quot;&gt;Это называется &lt;strong&gt;calling context required.&lt;/strong&gt; И подразумевает тот факт что дерево будет построено только из Composable функций. Так параметр Composer может быть передан ниже по дереву.&lt;/p&gt;
  &lt;p id=&quot;Z35a&quot;&gt;Composer является посредником между кодом Compose который мы пишем и компилятором. Composable функции используют его для того, чтобы сообщать о своих изменениях, создавать in-memory представление, а также обновлять состояние.&lt;/p&gt;
  &lt;p id=&quot;r2fy&quot;&gt;&lt;strong&gt;Идемпотентность&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;rVxb&quot;&gt;Composable функции ожидаемо должны быть идемпотентны относительно ноды дерева где они произведены. Перезапуск Composable функции с одними и теми же параметрами много раз должен приводить к тому, что результат будет храниться в том же месте в дереве. Jetpack Compose runtime полагается на такие механизмы как рекомпозиция.&lt;/p&gt;
  &lt;p id=&quot;wcNk&quot;&gt;В Jetpack Compose рекомпозиция является действием в ответ на повторный запуск функции. В момент ее выполнения могут произойти изменения в дереве функций. Runtime должен иметь возможность пересобирать функции время от времени при изменении их параметров по разным причинам.&lt;/p&gt;
  &lt;p id=&quot;trUC&quot;&gt;Процесс рекомпозиции проходит вниз по дереву компонентов проверяя какие из них подлежат изменению. Пропуск ноды дерева возможен в том случае если представленная Composable функция является той же самой и ее перезапуск приведет к тому же самому результату.&lt;/p&gt;
  &lt;p id=&quot;s5B5&quot;&gt;&lt;strong&gt;Отсутствие бесконтрольных сайд - эффектов&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;8CSU&quot;&gt;Сайд - эффект - это любое действие которое происходит без контроля во время вызова функции. Чтение локальных файлов, походы в сеть и кэш или установка глобальной переменной рассматриваются как сайд - эффекты. Они делают вызываемую функцию зависимой от внешних факторов которые могут иметь влияние на ее поведение.&lt;/p&gt;
  &lt;p id=&quot;DNhY&quot;&gt;Сайд - эффекты в контексте Compose это плохо. Composable функция должна быть чистой функцией. Compose ожидает предсказуемость от функций. Таким образом они могут быть многократно перезапущены. Многократный запуск функции дающий разные результаты повлияет на актуальность состояния производимого функцией.&lt;/p&gt;
  &lt;p id=&quot;cMDC&quot;&gt;Другой распространенный пример - зависимость Composable функций друг от друга. Такое поведение должно быть исключено!&lt;/p&gt;
  &lt;p id=&quot;PGB9&quot;&gt;Для работы с сайд эффектами в контролируемой среде в Jetpack Compose есть Effect Handlers (обработчики сайд-эффектов). Они позволяют делать асинхронные операции с привязкой к жизненному циклу функций.&lt;/p&gt;
  &lt;p id=&quot;uYpk&quot;&gt;&lt;strong&gt;Перезапуск&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;VDKq&quot;&gt; Ранее было упомянуто, что Composable функции это не стандартные функции, которые могут быть вызваны лишь разово и вызывать из себя еще функции. Composable функции могут перезапускаться во время рекомпозиции.&lt;/p&gt;
  &lt;p id=&quot;nrB1&quot;&gt;Compose выборочно решает какой ноде нужно выполниться. Эти функции спроектированы для многократного вызова и обновления состояния.&lt;/p&gt;
  &lt;p id=&quot;wjxX&quot;&gt;&lt;strong&gt;Мемоизация (Positional memoization)&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;r9km&quot;&gt;Positional Memoisation - это возможность функции закэшировать ее результат основываясь на входных данных. Таким образом у нас отпадает необходимость повторного вызова функции.&lt;/p&gt;
  &lt;p id=&quot;L0aw&quot;&gt;В функциональной мемоизации вызов функции будет идентифицирован через комбинацию ее параметров имени, типа, значений. Уникальный ключ для такой функции будет сгенерирован на основе ее сигнатуры. В Compose мемоизация основывается на их местоположении. В runtime будут сгенерированы разные id (уникальные в пределах родителя), когда одна и та же функция с одними и теми же параметрами вызывается из разных мест.&lt;/p&gt;
  &lt;figure id=&quot;vITZ&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/26/33/2633bd39-f456-4729-8d02-c469419e8c61.png&quot; width=&quot;700&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;RUIz&quot;&gt;Идентификатор сохранется во время рекомпозиции. Рантайм таким образом может узнавать, была ли вызвана функция ранее и нужно ли ее пропустить в момент рекомпозиции. Иногда сохранять уникальные идентификаторы бывает проблематично. К примеру возьмем случай, когда мы рисуем список в цикле.&lt;/p&gt;
  &lt;figure id=&quot;22NU&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/85/41/85413e8b-62e0-4da8-acad-e4414357264f.png&quot; width=&quot;314&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;MSs0&quot;&gt;В этом примере функция Talk(talk) вызывается в одном и том же месте, но представляет разные элементы списка и как следствие разные ноды в дереве. В подобном случае Compose Runtime полагается на порядок вызовов и генерирует идентификаторы с его учетом. Это работает хорошо, при добавлении элемента в конец списка, когда остальные элементы остаются на тех же позициях что и прежде. Но, что произойдет если мы добавим элементы наверх или в середину списка? Элементы списка рекомпозируются, так как их позиции будут смещены, даже если их содержимое не изменилось. Это крайне неэффективно в примерах, где мы работаем с большими списками. Для решения этой проблемы Compose предлагает использовать ключи. Мы можем явно задать ключ элементу списка&lt;/p&gt;
  &lt;figure id=&quot;5D88&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3d/11/3d11624a-68fa-4e5d-987d-efd8414abaa9.png&quot; width=&quot;398&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;0WT4&quot;&gt;В приведенном выше примере мы используем &lt;a href=&quot;http://talk.id/&quot; target=&quot;_blank&quot;&gt;Talk.id&lt;/a&gt; как уникальный для каждого элемента списка идентификатор. Таким образом мы сохраняем идентичность элементов независимо от их позиции.&lt;/p&gt;
  &lt;p id=&quot;hcK8&quot;&gt;Также часто разработчики хотят оперировать какими - то тяжело вычисляемыми параметрами в рамках Composable функций. Другими словами, мы хотим сохранять результат тяжело вычисляемых операций. Для этого Compose Runtime предоставляет нам &lt;strong&gt;remember&lt;/strong&gt; функцию.&lt;/p&gt;
  &lt;figure id=&quot;uc1L&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6b/6f/6b6f2c0a-35de-44c7-9346-1509c6b23e51.png&quot; width=&quot;548&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;z8pq&quot;&gt;Функция remember - это Composable функция, которая знает как читать и записывать что - то в in-memory структуру, хранящую состояние дерева. Она использует механизм позиционной мемоизации. Мемоизация работает не на глобальном уровне приложения в общем, а в рамках жизненного цикла Composable функции&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;p id=&quot;Tvb8&quot;&gt;&lt;strong&gt;Сходство с suspend функциями&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;qwwB&quot;&gt;В Kotlin приостанавливаемые функции могут вызываться только из других приостанавливаемых функций. Они также полагаются на контекст вызова (calling context).&lt;/p&gt;
  &lt;p id=&quot;u9Py&quot;&gt;Это гарантирует что suspend функции могут быть связаны в цепочку друг с другом и дает Koltin компилятору возможность прокинуть или заинжектить что - то через все уровни вычисления. Параметр Continuation передается в конце последним параметром функции и обеспечивает доступ к продвинутым функциям языка Kotlin.&lt;/p&gt;
  &lt;p id=&quot;ktU7&quot;&gt;Continuation несет в себе информацию, которая необходима рантайму Kotlin’a для запуска и приостановки данной функции. Такими же свойствами наделяет функцию аннотация @Composable. Она делает из стандартной Kotlin функции перезапускаемую, реактивную и тд.. функцию. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Дополнительно&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;OdX6&quot;&gt;Composable функции имеют различные ограничения, возможности в отличии от стандартных функций. Это все можно представить как форму function coloring. Так как они представляют разные категории функций.&lt;/p&gt;
  &lt;p id=&quot;7ihR&quot;&gt;function coloring - концепт представленный Бобом Нилстромом из команды Dart в Google.&lt;/p&gt;
  &lt;p id=&quot;ScgG&quot;&gt;Боб делит разные функции на категории. suspend функции тоже маркируются определенным образом. У нас есть возможность вызывать одну suspend функцию из другой. Совмещение стандартного программирования с асинхронным требует наличие механизмов интеграции (coroutine launch points).&lt;/p&gt;
  &lt;p id=&quot;5Y6R&quot;&gt;Jetpack Compose тоже нуждается в таких точках интеграции. Этим может выступать функция setContent { }.&lt;/p&gt;
  &lt;figure id=&quot;70dB&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/20/1e/201e522b-8e0a-48f8-89a7-6cd62ee68270.png&quot; width=&quot;846&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ASwb&quot;&gt;Как достигается возможность function coloring? Как показано на рисунке выше мы вызываем обычную функцию forEach из Column { } которая является @Composable функцией. Это возможно благодаря inline! Операторы коллекций объявлены как inline.&lt;/p&gt;
  &lt;p id=&quot;dxLW&quot;&gt;&lt;strong&gt;Типы Composable функций&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;m2p0&quot;&gt;Аннотация Composable меняет тип функции в compile time. C точки зрения синтаксиса тип Composable функции это @Composable (T) -&amp;gt; A, где А может быть Unit или любым другим типом, если функция возвращает значение. Разработчики используют эту возможность чтобы объявлять лямбды Composable, также как они это делают в Kotlin.&lt;/p&gt;
  &lt;figure id=&quot;BkQk&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7b/86/7b86558c-78eb-4d55-90c6-1020401cb9fd.png&quot; width=&quot;1058&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;89Yz&quot;&gt;У таких функций есть свой скоуп @Composable Scope.() -&amp;gt; A часто используемый для компоновки внутренней информации функций которые также являются Composable. Компилятор проводит статическую валидацию данных, определяет порядок вызова функций и многое другое.&lt;/p&gt;

</content></entry></feed>