Как заставить вызовы некоторым конструкторам/функциям использовать именованные аргументы?

У меня есть некоторые конструкторы и функции, которые я бы всегда вызывал с именованными аргументами. Есть ли способ потребовать это?

Я хотел бы иметь возможность сделать это для конструкторов и функций со многими параметрами и для тех, которые читаются более четко при использовании именованных аргументов и т.д.

Ответ 1

Я нашел способ сделать это в Kotlin 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> является незаконным в Kotlin, значение для vararg nothings: Nothing не может быть создано для передачи в (если не считать отражения). Это кажется немного взломанным, хотя и я подозреваю, что в байтоде есть некоторые накладные расходы для пустого массива типа Nothing, но он, похоже, работает.

Этот подход не работает для первичных конструкторов класса данных, которые не могут использовать vararg, но они могут быть помечены как private, а вторичные конструкторы могут использоваться с vararg nothings: Nothing.

Этот подход, однако, не работает в Kotlin 1.1: "Запрещенный тип параметра vararg: Nothing".:-(

К счастью, в Котлине нет надежды. Вы можете реплицировать этот шаблон, указав свой собственный пустой класс с помощью частного конструктора (например, Nothing) и используя это как первый параметр varargs. Конечно, это не должно было быть сделано, если форсированные именованные аргументы были официально поддержаны.