Kotlin
Propriétés déléguées
Recherche…
Introduction
Kotlin peut déléguer l'implémentation d'une propriété à un objet gestionnaire. Certains gestionnaires standard sont inclus, tels que l'initialisation différée ou les propriétés observables. Des gestionnaires personnalisés peuvent également être créés.
Initialisation paresseuse
val foo : Int by lazy { 1 + 1 }
println(foo)
L'exemple imprime 2
.
Propriétés observables
var foo : Int by Delegates.observable("1") { property, oldValue, newValue ->
println("${property.name} was changed from $oldValue to $newValue")
}
foo = 2
L'exemple des impressions foo was changed from 1 to 2
Propriétés sauvegardées sur la carte
val map = mapOf("foo" to 1)
val foo : String by map
println(foo)
L'exemple imprime 1
Délégation personnalisée
class MyDelegate {
operator fun getValue(owner: Any?, property: KProperty<*>): String {
return "Delegated value"
}
}
val foo : String by MyDelegate()
println(foo)
L'exemple imprimé Delegated value
Délégué Peut être utilisé comme couche pour réduire le passe-partout
Considérons le système de type nul de Kotlin et WeakReference<T>
.
Donc, supposons que nous devions sauvegarder une sorte de référence et que nous voulions éviter les fuites de mémoire, voici où WeakReference
entre en jeu.
Prenons par exemple ceci:
class MyMemoryExpensiveClass {
companion object {
var reference: WeakReference<MyMemoryExpensiveClass>? = null
fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
reference?.let {
it.get()?.let(block)
}
}
}
init {
reference = WeakReference(this)
}
}
Maintenant, c'est juste avec un WeakReference. Pour réduire ce niveau, nous pouvons utiliser un délégué de propriété personnalisé pour nous aider ainsi:
class WeakReferenceDelegate<T>(initialValue: T? = null) : ReadWriteProperty<Any, T?> {
var reference = WeakReference(initialValue)
private set
override fun getValue(thisRef: Any, property: KProperty<*>): T? = reference.get()
override fun setValue(thisRef: Any, property: KProperty<*>, value: T?) {
reference = WeakReference(value)
}
}
Donc maintenant, nous pouvons utiliser des variables qui sont enveloppées avec WeakReference
tout comme les variables WeakReference
normales!
class MyMemoryExpensiveClass {
companion object {
var reference: MyMemoryExpensiveClass? by WeakReferenceDelegate<MyMemoryExpensiveClass>()
fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
reference?.let(block)
}
}
init {
reference = this
}
}