Когда определения типов отвлекают от значения вашего кода из-за нечитабельности, выразительности или просто длины, у 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