type | layout | category | title | url |
---|---|---|---|---|
doc |
reference |
Syntax |
Приведение и проверка типов |
Мы можем проверить принадлежит ли объект к какому-либо типу во время исполнения с помощью оператора is
или его отрицания !is
:
if (obj is String) {
print(obj.length)
}
if (obj !is String) { // то же самое, что и !(obj is String)
print("Not a String")
}
else {
print(obj.length)
}
Во многих случаях в Kotlin вам не нужно использовать явные приведения, потому что компилятор следит за is
-проверками для
неизменяемых значений и вставляет приведения автоматически, там, где они нужны:
fun demo(x: Any) {
if (x is String) {
print(x.length) // x автоматически преобразовывается в String
}
}
Компилятор достаточно умён для того, чтобы делать автоматические приведения в случаях, когда проверка на несоответствие типу (!is
)
приводит к выходу из функции:
if (x !is String) return
print(x.length) // x автоматически преобразовывается в String
или в случаях, когда приводимая переменная находится справа от оператора &&
или ||
:
// x автоматически преобразовывается в String справа от `||`
if (x !is String || x.length == 0) return
// x автоматически преобразовывается в String справа от `&&`
if (x is String && x.length > 0) {
print(x.length) // x автоматически преобразовывается в String
}
Такие умные приведения работают вместе с when-выражениями и циклами while:
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
Заметьте, что умные приведения не работают, когда компилятор не может гарантировать, что переменная не изменится между проверкой и использованием. Более конкретно, умные приведения будут работать:
- с локальными val переменными - всегда;
- с val свойствами - если поле имеет модификатор доступа
private
илиinternal
, или проверка происходит в том же модуле, в котором объявлено это свойство. Умные приведения неприменимы к публичным свойствам или свойствам, которые имеют переопределённые getter'ы; - с локальными var переменными - если переменная не изменяется между проверкой и использованием и не захватывается лямбдой, которая её модифицирует;
- с var свойствами - никогда (потому что переменная может быть изменена в любое время другим кодом).
Обычно оператор приведения выбрасывает исключение, если приведение невозможно, поэтому мы называем его небезопасным. Небезопасное приведение в Kotlin выполняется с помощью инфиксного оператора as (см. приоритеты операторов):
val x: String = y as String
Заметьте, что null не может быть приведен к String
, так как String
не является nullable,
т.е. если y
- null, код выше выбросит исключение. Чтобы соответствовать семантике приведений в Java, нам нужно указать nullable тип в правой части приведения:
val x: String? = y as String?
Чтобы избежать исключения, вы можете использовать оператор безопасного приведения as?, который возвращает null в случае неудачи:
val x: String? = y as? String
Заметьте, что несмотря на то, что справа от as? стоит non-null тип String
, результат приведения является nullable.