Alan B
12/08/2022, 9:31 PM/*
I'm working on a function to copy values from one instance to another.
At the moment I don't care about nullability, or type mismatches for field values.
Two data classes. Copy Public's matching properties from Private into Public.
*/
data class Private(val a: String, val b: String)
data class Public(val a: String)
// This next function works "fine" but it's obviously typed to the receiver and has zero reuse.
// Note: I have no idea what or why this receiver is what it is with the this@toPublic
fun Private.toPublic(): Public {
val constructor = Public::class.primaryConstructor ?: error("No primary constructor found")
val propertiesByName = Private::class.memberProperties.associateBy { it.name }
return constructor.callBy(constructor.parameters.associateWith { parameter ->
when (parameter.name) {
// Eventually plan on adding a map to the function
// so properties can be mapped to unmatched names, or coerced to other types
// Note: I have no idea what or why this receiver is what it is with the this@toPublic
else -> propertiesByName[parameter.name]?.get(this@toPublic) // <-- so confused with the receiver
}
})
}
val privateOne = Private(a = "A", b = "B")
val publicOne = privateOne.toPublic()
// publicOne now has its 'a' value copied from privateOne
/*
Now imagine that function above but make it a reusable. This is now more pseudocode as it will not compile,
and it's just wrong because I'm dumb in this area. What is the receiver to be in such a case on that else line?
*/
inline fun <reified R> toPublic(input: Any, output: R & Any): R {
val constructor = output::class.primaryConstructor ?: error("No primary constructor found?")
val propertiesByName = input::class.memberProperties.associateBy { it.name }
val result: R = constructor.callBy(constructor.parameters.associateWith { parameter ->
when (parameter.name) {
// I have absolutely no clue as to what the receiver is here
else -> propertiesByName[parameter.name]?.get(input) // <-- so confused with the receiver
}
})
return result
}
// what I would like to do
fun Private.toPublic2() = toPublic(this, Public::class)
/*
Again, my confusion is on the receivers.
Thanks for your time.
*/
Alan B
12/09/2022, 1:13 PM