Приведение — это необходимое зло в программировании. Мы обожаем его ненавидеть. В Kotlin выполнять приведение намного приятнее, чем в Java. Читайте ниже об очень известном, малопонятном и чрезвычайно удобном.
Умное приведение в Kotlin
Если мы хотим безопасно привести что-то к чему-то в Java, то лучше сначала все проверить, а затем выполнить приведение следующим образом:
private void checkBeforeCast(Object anything) {
if (anything instanceof String) {
println(((String)anything).length());
}
}
Как вы видите из примера выше, несмотря на проверку, вам все равно приходится использовать явное приведение для типа String
.
В Kotlin
Уже известно, что anything
— это String
, поэтому пишем код для умного приведения его к String
.
private fun checkBeforeCast(anything: Any) {
if (anything is String) {
println(anything.length)
}
}
CastOrNull в Kotlin: оператор as?
Предположим, мы хотим привести переменную к типу и вернуть null
, если приведение не выполнится.
В Java нам бы пришлось написать явный код с проверкой и вернуть null
.
private String castOrNull(Object anything) {
if (anything instanceof String) {
return (String)anything;
}
return null;
}
В Kotlin
Используется ключевое слово as?
. Оно либо успешно выполняет приведение к данному типу, либо возвращает null
при неудаче.
private fun castOrNull(anything: Any): String? {
return anything as? String
}
GenericCastOrNull в Kotlin: оператор reified + as?
Пример выше показывает приведение к определенному типу. В Java, если нам потребуются обобщения, которые можно задавать для приведения к любому типу, то придется прибегнуть сразу к двум структурам: T
и Class<T>
.
private <T> T genericCastOrNull(Object anything, Class<T> clazz) {
if (clazz.isInstance(anything)) {
return (T)anything;
}
return null;
}
Вызов этого класса выглядит так:
String myString = genericCastOrNull(anything, String.class)
В Kotlin
Можно достичь того же самого следующим синтаксисом:
private inline fun <reified T> genericCastOrNull(anything: Any):T? {
return anything as? T
}
Вызов функции выглядит так:
val myString = genericCastOrNull<String>(anything)
Перевод статьи Elye: Kotlin made casting so much neater