Недавно я читал проект с открытым исходным кодом и наткнулся на функцию, которую мне было трудно понять. Не потому, что это было сложно или что-то в этом роде, а потому, что это была функция в чистом идиоматическом Котлине. Потом я понял, что недостаточно глубоко вникал в язык. Я пишу эту статью, чтобы поделиться знаниями, которые я собрал с помощью одной функции, и, надеюсь, она поможет и другим людям. Давайте погрузимся в это, не так ли? Функция выглядит следующим образом:

internal inline fun <reified T : Activity> Context.startActivity(block: Intent.() -> Unit = {}) {
    val intent = Intent(this, T::class.java)
    block(intent)
    startActivity(intent)
}

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

internal: первое свойство — internal, которое является модификатором видимости, уникальным для Kotlin. Функцию со свойством internal можно использовать только в модуле, к которому она принадлежит (группа файлов, которые компилируются вместе). Это означает, что вы не можете использовать эту функцию в классе, который находится в модуле, отличном от класса, в котором функция была определена.

inline: это низкоуровневая функция, которая указывает компилятору вставлять тело функции везде, где эта функция требуется, а не выделять память при вызове этой функции. Его основным преимуществом является оптимизация производительности за счет сокращения накладных расходов памяти на вызов функции. Рекомендуется использовать его, когда ваша функция невелика.

reified. Наше следующее ключевое слово здесь — reified, что в основном дает нам возможность узнать тип класса во время выполнения. В обычных условиях это невозможно сделать из-за происходящего стирания типа. Единственный способ добиться этого - добавить класс в качестве параметра. Но это решение более громоздкое, чем что-либо другое. Ключевое слово reified намного чище. Итак, в этой функции мы используем reified, потому что нам нужен целевой класс активности, чтобы использовать его в объекте Intent. Следует отметить, что reified можно использовать только в встроенной функции.

Context.startActivity: здесь мы фактически определяем функцию-расширение. функция расширения дает нам возможность расширять функциональные возможности существующих классов без необходимости их наследования. В данном случае мы создаем функцию для принимающего объекта типа Context. Важно отметить, что внутри тела функции использование ключевого слова this ссылается на принимающий объект, который здесь имеет тип Context.

Intent.(): следующий параметр — это параметр функции. Здесь мы видим, что фактически имеем дело с другой функцией расширения для принимающего объекта типа Intent. Единственная разница здесь в том, что функция не принимает параметров и ничего не возвращает (Примечание: в Kotlin функция всегда возвращает значение или объект, в данном конкретном случае возвращается объект типа Any, когда явно ничего не возвращается). Параметр ‘block’ является принимающим объектом этой функции. То, что происходит в теле основной функции (startActivity), немного тонкое, когда мы вызываем блок (намерение), он действует как функция области применения, т. е. дает вам доступ к свойствам объекта и возможность их настройки. на объекте, через который мы его передаем (намерение здесь). В конце концов, наш объект модифицируется с внесением желаемых изменений.

Когда мы вызываем эту функцию, она будет выглядеть так:

startActivity<DummyActivity> {
    putExtra(KEY, it)
}

putExtra — это свойство настройки объекта Intent, и мы используем его для добавления данных в наше намерение, тем самым изменяя его. Если бы мы хотели просто перейти к DummyActivity без передачи каких-либо данных, мы могли бы вызвать функцию следующим образом:

startActivity<DummyActivity>()

Вот и все. мы получили все это покрыто. По сути, функция при вызове просто переходит от одного действия к другому, но мы видели так много идиоматического синтаксиса Kotlin в процессе в такой маленькой функции. Мы можем добиться многого, оставаясь при этом очень краткими и читабельными.