2016-10-29 2 views
3

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

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)) { 

    } 

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

ответ

3

Variable number of arguments (vararg) кажется, подходит ваш случай использования очень хорошо, но только если вы можете отказаться от null в качестве значения по умолчанию для conditions так vararg не может быть обнуляемым (например, использование 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 чем использовать named arguments и распространение оператора:

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 
Смежные вопросы