Smart casting, Kotlin derleyicisinin belirli bir tür veya null olarak kontrol edildikten sonra otomatik olarak türü "düşürdüğü" bir mekanizmadır. Bu, dönüşüm gerçekleştirilen türün özelliklerini ve yöntemlerini açık bir dönüştürme olmadan kullanmanıza olanak tanır.
fun demo(x: Any) { if (x is String) { println(x.length) // x otomatik olarak String'e dönüştürüldü } }
Şunlarla çalışır:
is / !is operatörleri (örneğin, if veya when içinde)if (x != null))when ifadeleriŞunlarla çalışmaz:
val str: String? = getString() if (str != null) println(str.length) // smart cast
val something: Any get() = fetch() if (something is String) { println(something.length) // Hata: smart cast mümkün değil }
Metotlar içinde sınıf open veya var özellikleri için smart cast'a güvenebilir miyiz?
Hayır! Smart cast yalnızca yerel değişkenlerle ve final sınıflardaki val özelliklerle çalışır. Açık (open) veya var özelliklerde, derleyici diğer threadler veya alt sınıflar tarafından değerin değişip değişmeyeceğinden emin olamaz. Bunlar için manuel cast veya yerel bir değişken gerekir.
open class Base { open var maybeString: Any? = "abc" fun check() { if (maybeString is String) { // println(maybeString.length) // Hata: Smart cast mümkün değil val asString = maybeString as String println(asString.length) // Açık cast } } }
Hikaye
Bir projede ekran mantığı için open var model veri özellikleri kullanıldı. Programcı if (model is SomeType) kontrolünden sonra smart-cast’a güvendi, ancak derleme sırasında tüm türleri manuel olarak döndürmek zorunda kaldı, bu da okunabilirliği azalttı ve kod tekrarı ekledi, çünkü smart cast'ın var/open üzerindeki kısıtlamalarını bilmiyordu.
Hikaye
Getter (örneğin, bir delegasyon veya doğrulama yoluyla) aracılığıyla veri alırken, değerin smart cast'ı çalışmadı. Geliştirici nedenlerini anlamadı ve birkaç saat debug yaptı, derken derleyicinin böyle getter'lara smart cast uygulamadığını öğrendi çünkü çağrılar arasında farklı değerler döndürebiliyorlardı.
Hikaye
Nullable değerleri if (obj != null) ile işlerken smart cast, branş içinde çalıştı, ancak kodu paralel hale getirdiğinde garanti alanının dışında yapılan çağrılardan NullPointerException ortaya çıktı. Bu, smart cast'ın yerel eylemi ve nullable değişkenlerle çoklu thread senaryolarındaki özelliklerine dair yetersiz bir anlayışı gösterdi.