Is there any Kotlin'ish way to use default values ...
# announcements
m
Is there any Kotlin'ish way to use default values of function and constructor parameters programmatically or is this only possible with reflection and relying on the internals of the synthetic overloads (which also only works on the JVM)?
Copy code
class Test(val a: Int = 1, val b: Int = 2, val c: Int = 3)

fun test() {
	var a: Int? = null
	var b: Int? = null
	var c: Int? = null
	if (someCondition) a = somethingNonNull
	if (someCondition) b = somethingNonNull
	if (someCondition) c = somethingNonNull

	Test(
		a = a ?: howToUseDefaultValue, // ??
		b = b ?: howToUseDefaultValue, // ??
		c = c ?: howToUseDefaultValue // ??
	)
}
n
You can define the defaults as constants (vals) and refer to the constants within the body of the function.
m
No, I can't change the code of the file as I'm in annotation processing world 🙂 Also way too much unnecessary work.
n
Ok. I thought you were writing the function itself
m
In some cases I am, but I'm looking for a general solution close to Kotlin world without reinventing defaults
a
This is (kind of) what Moshi does:
Copy code
fun test() {
    // ...

    val defaults = Test()
    Test(
        a = a ?: defaults.a,
        b = b ?: defaults.b,
        c = c ?: defaults.c
    )
}
m
only works if everything is optional which it isn't in most cases 😕
also can have nasty side-effects when the class a) has a non-trivial initialzier b) does something completely different in the default constructor
It's merely a workaround to the actual issue. I'd prefer reflection in that case 😅
a
Here’s the case when there’s required
d
Copy code
var result = Test(
        d = d ?: throw ...
)
result = Test(
        a = a ?: result.a,
        b = b ?: result.b,
        c = c ?: result.c,
        d = d ?: result.d)
return result
m
That's a way to create the instance indeed, but I'd make assumptions that there are no side-effects in the constructor / initializer 😕
✔️ 1