I want to compare values between multiple instances of a data class so that I know which value changed:
data class A(val name : String)
val firstA = A("hello")
val secondA = A("you")
if (secondA.name.changed(firstA)) {
// Do something
}
Can I somehow access the property function of .name
and execute it on another target value (in this example on firstA) without explicitly defining it?
Can delegates help here or how do I solve this with and without reflection?
I found a way without using reflection:
interface DiffValue<T> {
val old : T?
}
fun <T,R> T.changed(memberAccess : T.() -> R) : Boolean {
if (this is DiffValue<*>) {
val old = this.old as? T
if (old != null) {
val currentValue = with(this, memberAccess)
val previousValue = with(old, memberAccess)
return currentValue != previousValue
}
}
return true
}
And this is how you use it:
data class A(val name: String, override val old : A? = null): DiffValue<A>
val firstA = A("hello")
val secondA = A("you", firstA)
if (secondA.changed {name}) {
// Do something
}
This is based on the concept of lambda literals with receivers that allows Kotlin to build powerful builders and DSLs.
Note: The DiffValue
interface is optional and is just used to make it a bit easier to keep values together and avoids an additional parameter in changed
.