Я нашел способ сделать это в Котлин 1.0 с помощью Nothing
из STDLIB:
/* 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
в Array<Nothing>
является незаконным в Котлин, значение для vararg nothings: Nothing
не может быть создан, чтобы быть переданы в (короткое отражения я полагаю). Это кажется немного взломанным, хотя и я подозреваю, что в байтоде есть некоторые накладные расходы для пустого массива типа Nothing
, но он работает.
Этот подход не работает для первичных конструкторов класса данных, которые не могут использовать vararg
, но они могут быть помечены как private
, а вторичные конструкторы могут использоваться с vararg nothings: Nothing
.
Этот подход, однако, не работает в Kotlin 1.1: «Запретный параметр параметра vararg: Nothing». :-(
К счастью, в Kotlin 1.1 не теряется надежда. Вы можете реплицировать этот шаблон, указав свой собственный пустой класс с помощью частного конструктора (например, Nothing
) и используя его в качестве первого параметра varargs. Конечно, это не нужно было бы делать, если бы форсированные именованные аргументы были официально поддержаны.
Релевантная ошибка Kotlin: https://youtrack.jetbrains.com/issue/KT-14934 –