how can be known if bar is null because no value was passed or because null was passed? I.e. the function was called as foo() or foo(bar = null)?
Actual case:
data class State(
val foo: String? = null,
val bar: Int? = null,
val baz: Long? = null,
)
class StateManager {
var state: State
private set
fun setState(
foo: String? = null,
bar: Int? = null,
baz: Long? = null,
) {
state = state.copy(foo, bar, baz)
}
}
This example is not working, because setState(bar = 1) overrides with nullfoo and baz variables. state.copy(bar = 1) instead does not override foo and baz. I assume copy’s implementation is able to differentiate if null is provided as a parameter or if it is the default value.
The best I got:
fun setState(
val foo: String? = null,
val bar: Int? = null,
val baz: Long? = null,
) {
val copyRef = state::copy
val params = copyRef.parameters
val values = mutableMapOf<KParameter, Any?>()
if (foo != null) values[params[0]] = foo
if (bar != null) values[params[1]] = bar
if (baz != null) values[params[2]] = baz
state = copyRef.callBy(values)
}
This solution does not override with null unspecified values, but is not able to assign null when wanted.
Just to answer the original question, you can’t know if a function call is using a default value. When you call setState(bar = 1) the compiler basically changes the call to setState(null, 1, null).