Псевдонимы типов
Псевдонимы типов предоставляют альтернативные имена для существующих типов. Если имя типа слишком длинное, вы можете ввести другое, более короткое имя, и использовать его вместо первоначального.
Псевдонимы типов полезны, когда вы хотите сократить длинные имена типов, содержащих обобщения. К примеру, можно упрощать названия типов коллекций:
typealias NodeSet = Set<Network.Node>
typealias FileTable<K> = MutableMap<K, MutableList<File>>
Вы также можете объявить псевдонимы для функциональных типов:
typealias MyHandler = (Int, String, Any) -> Unit
typealias Predicate<T> = (T) -> Boolean
Вы можете ввести новые имена для внутренних или вложенных классов:
class A {
inner class Inner
}
class B {
inner class Inner
}
typealias AInner = A.Inner
typealias BInner = B.Inner
Псевдонимы типов не вводят новых типов. Они эквивалентны соответствующим базовым типам. Когда вы добавляете
typealias Predicate<T> и используете Predicate<Int> в своём коде, компилятор Kotlin всегда преобразует это в
(Int) -> Boolean. Таким образом, вы можете передать переменную своего типа туда, где требуется обычный
функциональный тип, и наоборот:
typealias Predicate<T> = (T) -> Boolean
fun foo(p: Predicate<Int>) = p(42)
fun main() {
val f: (Int) -> Boolean = { it > 0 }
println(foo(f)) // выведет "true"
val p: Predicate<Int> = { it > 0 }
println(listOf(1, -2).filter(p)) // выведет "[1]"
}
Вложенные псевдонимы типов
В Kotlin вы можете определять псевдонимы типов внутри других объявлений, если они не захватывают параметры типа из внешнего класса:
class Dijkstra {
typealias VisitedNodes = Set<Node>
private fun step(visited: VisitedNodes, ...) = ...
}
Захват означает, что псевдоним типа ссылается на параметр типа, определённый во внешнем классе:
class Graph<Node> {
// Некорректно, потому что захватывает Node
typealias Path = List<Node>
}
Чтобы исправить эту проблему, объявите параметр типа непосредственно в псевдониме типа:
class Graph<Node> {
// Корректно, потому что Node является параметром псевдонима типа
typealias Path<Node> = List<Node>
}
Вложенные псевдонимы типов делают код чище и удобнее в сопровождении: они улучшают инкапсуляцию, уменьшают количество объявлений на уровне пакета и упрощают внутренние реализации.
Правила для вложенных псевдонимов типов
Для вложенных псевдонимов типов действуют специальные правила, которые обеспечивают понятное и согласованное поведение:
- Вложенные псевдонимы типов должны соблюдать все существующие правила для псевдонимов типов.
- С точки зрения видимости псевдоним не может открывать больше доступа, чем позволяют типы, на которые он ссылается.
- Их область видимости такая же, как у вложенных классов. Их можно определять внутри классов, и они скрывают любые родительские псевдонимы типов с тем же именем, поскольку не переопределяют их.
- Вложенные псевдонимы типов можно помечать как
internalилиprivate, чтобы ограничить их видимость. - Вложенные псевдонимы типов не поддерживаются в
объявлениях
expect/actualKotlin Multiplatform.