Изменение типа с помощью typealias

Android

Когда определения типов отвлекают от значения вашего кода из-за нечитабельности, выразительности или просто длины, у Kotlin есть подходящая функция: typealias! Typealias позволяет давать альтернативные имена типам классов или функций, не вводя при этом новых.

Использование Typealias

Для именования типа функции можно использовать псевдонимы типов:

typealias TeardownLogic = () -> Unit
fun onCancel(teardown : TeardownLogic){ }

private typealias OnDoggoClick = (dog: Pet.GoodDoggo) -> Unit
val onClick: OnDoggoClick

Недостатком этого является то, что имя скрывает параметры, передаваемые в функцию, что снижает ее читабельность:

typealias TeardownLogic = () -> Unit //or
typealias TeardownLogic = (exception: Exception) -> Unit

fun onCancel(teardown : TeardownLogic){
// Сложно увидеть какая информация нам
// доступна в TeardownLogic
}

Typealias позволяет сократить длинные стандартные имена:

typealias Doggos = List<Pet.GoodDoggo>

fun train(dogs: Doggos){ … }

Но не торопитесь. Действительно ли использование псевдонима типа сделает код более осмысленным и читаемым?

Если вы работаете с длинным именем класса, можно использовать typealias, чтобы сократить его:

typealias AVD = AnimatedVectorDrawable

Но здесь лучше всего было бы использовать псевдоним импорта:

import android.graphics.drawable.AnimatedVectorDrawable as AVD

В этом случае использование ярлыка на самом деле не помогает повысить читабельность, а IDE поможет автоматически заполнить имя класса.

Но импорт псевдонимов полезен тогда, когда вам нужно устранить неоднозначность между классами с одинаковым именем, поступающими из разных пакетов:

import io.plaidapp.R as appR

import io.plaidapp.about.R

Псевдонимы типов определяются вне классов, поэтому убедитесь, что вы учитываете их видимость при использовании.

Использование typealias в кроссплатформенных проектах

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

Интерфейсы в обычном коде — это ожидаемые объявления, определенные с помощью ключевого слова expect. Реализация в коде платформы определяется с помощью ключевого слова actual. Если реализация уже существует в одной из платформ и имеет все ожидаемые методы с точно такими же сигнатурами, то вы можете использовать typealias для сопоставления имени класса с ожидаемым именем.

expect annotation class Test

actual typealias Test = org.junit.Test

Под капотом

Псевдонимы не создают новые типы. Например, декомпилированный код для функции train будет просто использовать List:

// Kotlin
typealias Doggos = List<Pet.GoodDoggo>
fun train(dogs: Doggos) { … }

// Декомпилированный Java код
public static final void train(@NotNull List dogs) { … }

Вы не должны полагаться на псевдонимы типов для проверки их времени компиляции. Вместо этого следует рассмотреть возможность использования другого типа или встроенного класса. Например, предположим, что у нас есть следующая функция:

fun play(dogId: Long)

Создание псевдонима типа Long не поможет предотвратить ошибки при попытке передать неверный идентификатор:

typealias DogId = Long

fun pet(dogId: DogId) { … }

fun usage() {
    val cat = Cat(1L)
    pet(cat.catId) // компилируется
}

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

Специально для сайта ITWORLD.UZ. Новость взята с сайта NOP::Nuances of programming