Котлин – вторичный конструктор, который отличается одним аргументом

У меня есть фрагмент кода Котлина, где первый и второстепенный конструктор сильно отличаются, см. Ниже

class InstructionPrototype constructor( val iname: String, val opcode: Int, val mnemonicExample: String, val numericExample: Int, val description: String, val format: Format, val pattern: Pattern, var type: Type? = null, var rt: Int? = null, var funct: Int? = null, var conditions: Array<(n: Int) -> String?>? = null) { constructor( iname: String, opcode: Int, mnemonicExample: String, numericExample: Int, description: String, format: Format, pattern: Pattern, type: Type?, rt: Int?, funct: Int?, condition: (n: Int) -> String? ): this(iname, opcode, mnemonicExample, numericExample, description, format, pattern, type, rt, funct, arrayOf(condition)) { } 

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

Переменная количество аргументов ( vararg ), по- видимому, подходит для вашего vararg использования очень хорошо, но только если вы можете отказаться от null в качестве значения по умолчанию для conditions поскольку vararg не может быть нулевым (например, use emptyArray() ):

 class InstructionPrototype constructor( val iname: String, val opcode: Int, val mnemonicExample: String, val numericExample: Int, val description: String, val format: Format, val pattern: Pattern, var type: Type? = null, var rt: Int? = null, var funct: Int? = null, vararg var conditions: (n: Int) -> String? = emptyArray()) 

На сайте использования вы можете передать одиночный (n: Int) -> String? , и он будет упакован в массив и в дополнение к передаче нескольких функций, разделенных запятой, вы можете использовать оператор спредов для передачи массива:

 f(vararg a: String) { } f("a") f("a", "b", "c") val array = arrayOf("a", "b", "c") f(*array) // any array of the correct type can be passed as vararg 

Кроме того, несколько параметров до conditions также имеют значения по умолчанию, и нет другого способа пропустить их и передать conditions чем использовать именованные аргументы и оператор с расширением:

 fun f(x: Int = 5, vararg s: String) { } f(5, "a", "b", "c") // correct f(s = "a") // correct f(s = "a", "b", "c") // error f(s = *arrayOf("a", "b", "c") // correct