Я не знал, что Kotlin может делать такое умное кастирование. Он достаточно умен, чтобы кастовать для вас автоматически, так что вам больше не нужно явно кастовать.
Эта статья была первоначально опубликована на vtsen.hashnode.dev 21 мая 2022 года.
Я совершенно упустил эту потрясающую возможность Kotlin в своем предыдущем посте — Полное сравнение синтаксиса C# и Kotlin.
Я узнал об этой умной функции только после 8 месяцев разработки Kotlin, и, возможно, я использовал ее, не зная об этом. IDE Android Studio позаботилась об этом!
Допустим, у вас есть BaseClass
и ChildClass
вот так.
open class BaseClass
class ChildClass(val value: Int): BaseClass()
и вы создаете объект ChildClass
, на который ссылается BaseClass
.
val obj: BaseClass = ChildClass(value = 7)
Чтобы получить доступ к данным в ChildClass
, вы выполняете явное приведение ниже.
val childObj = obj as ChildClass
childObj.value
Однако компилятор Kotlin может автоматически выполнить умное приведение в следующем сценарии:
Пример 1
fun smartCastExample1() {
val obj: BaseClass = ChildClass(value = 7)
//Calling obj.value here is not allowed
//because obj belongs to BaseClass
if (obj is ChildClass) {
//obj in this scope is smart cast to ChildClass.
//Thus, accessing the obj.value is allowed here
println("Child value is ${obj.value}")
//You don't need to explicit cast like this
val childObj = obj as ChildClass
println("Child value is ${childObj.value}")
}
}
obj
в этой области видимостиif
должен бытьChildClass
, поэтому компилятор Kotlin выполняет умное приведение.
Пример 2
fun smartCastExample2() {
val obj: BaseClass = ChildClass(value = 7)
if (obj !is ChildClass) return
// obj is smart cast to ChildClass
println("Child value is ${obj.value}")
}
obj
здесь должен бытьChildClass
, так как он был возвращен, если это не так.
Пример 3
fun smartCastExample3() {
val obj: BaseClass = ChildClass(value = 7)
// obj at right side of || is smart cast to ChildClass
if (obj !is ChildClass || obj.value == 7) return
}
Это
obj.value
оценивается только тогда, когдаobj
являетсяChildClass
. Если вы изменитеobj !is ChildClass
наobj is ChildClass
, умное приведение не будет работать.
Пример 4
fun smartCastExample3() {
val obj: BaseClass = ChildClass(value = 7)
// obj at right side of && is smart cast to ChildClass
if (obj is ChildClass && obj.value == 7) return
}
Аналогично примеру выше, вторая проверка выполняется только тогда, когда
obj
являетсяChildClass
. Если вы изменитеobj is ChildClass
наobj !is ChildClass
, умное приведение не будет работать.
Приведенный здесь пример — это приведение от супертипа к подтипу. Это также работает для нулевого типа к не нулевому. Другие примеры смотрите здесь.
См. также
- Советы и рекомендации по Kotlin