Ответ
Приведение типов (type casting) — это преобразование значения одного типа в другой. В Kotlin/Java есть два вида:
- Явное приведение (explicit) — требует указания типа:
val num: Int = 42
val longNum: Long = num.toLong() // явное
- Неявное приведение (implicit) — автоматическое, когда компилятор уверен в безопасности:
val longNum: Long = 42L
val doubleNum: Double = longNum.toDouble()
Важно:
- В Kotlin нет автоматического приведения для чисел (в отличие от Java)
- Для классов используется оператор
as(опасный) илиas?(безопасный):
val obj: Any = "String"
val str: String = obj as String // может выбросить ClassCastException
Smart casts работают, когда компилятор может доказать тип:
if (obj is String) {
println(obj.length) // автоматическое приведение
} Ответ 18+ 🔞
А, ну это про то, как одно в другое превращать, да? Типа, был у тебя целый бутерброд, а ты его в крошки покрошил — вроде то же самое, но уже не намажешь. Так вот, в Котлине с этим строго, не как в той старой Java, где всё само текло куда попало.
Смотри, есть два подхода, как бабка на базаре: либо ты прямо говоришь, что тебе надо, либо надеешься, что тебя поймут правильно.
Первый — явный, когда ты сам всё контролируешь. Ты прямо командуешь: «Эй, число, стань длинным!». И пишешь это в коде.
val num: Int = 42
val longNum: Long = num.toLong() // вот, явно сказал — toLong!
Второй — неявный, когда компилятор такой умный и сам догадывается. Но, блядь, в Котлине с числами он на такое почти не способен! Не то что в Джяве, где int в long сам залезет. Тут надо явно просить. Хотя для некоторых простых случаев работает:
val longNum: Long = 42L
val doubleNum: Double = longNum.toDouble() // опять toDouble, ёпта!
А теперь самое интересное — с объектами. Вот тут начинается цирк. Есть оператор as — это как прыжок с парашютом без проверки строп. Может, полетишь, а может, пиздец.
val obj: Any = "String"
val str: String = obj as String // Всё ок, obj — строка. Но если бы там было число — ClassCastException, и привет, программа накрылась медным тазом.
Поэтому умные люди используют безопасный as?, который в случае провала просто вернёт null. Не летит в пропасть, а аккуратно говорит: «Не, чувак, не вышло».
val notAString: Any = 12345
val str: String? = notAString as? String // str будет null, а не краш. Уже лучше.
Но есть же и магия — умные приведения (smart casts). Это когда компилятор, видя твою проверку, сам всё понимает. Красота, ядрёна вошь!
if (obj is String) {
println(obj.length) // Внутри этого if компилятор УЖЕ ЗНАЕТ, что obj — String. Можно сразу length вызывать, без всяких 'as'. Сам додумался!
}
Вот и вся философия. Не надеяться на авось, а явно указывать, что во что превращать. А компилятор, если видит, что ты уже проверил, — поможет и сделает всё сам. Главное — не пытаться запихнуть Int в String через as, а то будет тебе хиросима, а не программа.