I have some constructors and functions that I'd like to always be called with named arguments. Is there a way to require this?
I'd like to be able to do this for constructors and functions with many parameters and for those that read more clearly when named arguments are used, etc.
In Kotlin 1.0 you can do this by using Nothing
from the stdlib.
In Kotlin 1.1+ you will get "Forbidden vararg parameter type: Nothing" but you can replicate this pattern by defining your own empty class with a private constructor (like Nothing
), and using that as the first varargs parameter.
/* requires passing all arguments by name */
fun f0(vararg nothings: Nothing, arg0: Int, arg1: Int, arg2: Int) {}
f0(arg0 = 0, arg1 = 1, arg2 = 2) // compiles with named arguments
//f0(0, 1, 2) // doesn't compile without each required named argument
/* requires passing some arguments by name */
fun f1(arg0: Int, vararg nothings: Nothing, arg1: Int, arg2: Int) {}
f1(arg0 = 0, arg1 = 1, arg2 = 2) // compiles with named arguments
f1(0, arg1 = 1, arg2 = 2) // compiles without optional named argument
//f1(0, 1, arg2 = 2) // doesn't compile without each required named argument
It also works in Kotlin 1.7 with Nothing
, but it's necessary to suppress the compilation error:
...
@Suppress("FORBIDDEN_VARARG_PARAMETER_TYPE", "UNUSED_PARAMETER")
vararg nothings: Nothing,
...
As Array<Nothing>
is illegal in Kotlin, a value for vararg nothings: Nothing
can't be created to be passed in (short of reflection I suppose). This seems a bit of a hack though and I suspect there is some overhead in the bytecode for the empty array of type Nothing
but it appears to work.
This approach does not work for data class primary constructors which cannot use vararg
but these can be marked as private
and secondary constructors can be used with vararg nothings: Nothing
.