2016-05-23 11 views
12

Ich habe einige Konstruktoren und Funktionen, die ich immer mit benannten Argumenten aufgerufen werden möchte. Gibt es eine Möglichkeit, dies zu verlangen?Wie kann ich Aufrufe an einige Konstruktoren/Funktionen zwingen, benannte Argumente zu verwenden?

ich mit vielen Parametern für Konstrukteure und Funktionen dieses in die Lage sein mag, dass zu tun, und für diejenigen, die mehr deutlich zu lesen, wenn benannte Argumente verwendet werden, usw.

+1

Relevanter Kotlin-Fehler: https://youtrack.jetbrains.com/issue/KT-14934 –

Antwort

13

ich einen Weg gefunden habe, dies in Kotlin zu tun 1,0 von Nothing vom stdlib mit:

/* 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 

Als Array<Nothing> ist illegal in Kotlin, ein Wert für vararg nothings: Nothing kann nicht in erstellt werden, um übergeben werden (kurze Reflexions nehme ich an). Dies scheint ein bisschen ein Hack und obwohl ich vermute, gibt es einige Overhead im Bytecode für das leere Array vom Typ Nothing, aber es scheint zu funktionieren.

Dieser Ansatz funktioniert nicht für primäre Konstruktoren der Datenklasse, die nicht verwenden können, aber diese können als private markiert werden und sekundäre Konstruktoren können mit vararg nothings: Nothing verwendet werden.

Dieser Ansatz funktioniert jedoch nicht in Kotlin 1.1: "Verboten Vararg Parametertyp: Nichts". :-(

Glücklicherweise ist Hoffnung in Kotlin 1.1 nicht verloren. Sie können dieses Muster replizieren, indem Sie Ihre eigene leere Klasse mit einem privaten Konstruktor (wie Nothing) definieren und diesen als ersten varargs-Parameter verwenden. dies wäre nicht erforderlich, wenn erzwungene benannte Argumente formal unterstützt würden.

+14

Während dies vom Design der Sprache nie beabsichtigt war Ich applaudiere deinen Einfallsreichtum :) –

+0

Sie können ein Array von Nothing mit * arrayOf () verbreiten. Oder du solltest in der Lage sein, ich denke – Deanveloper

+0

@Deanveloper Ich habe es gerade ausprobiert. Ich bekomme: "Nicht unterstützt [Array im Rückgabetyp ist illegal" und "kann 'Nothing' nicht als verdingter Typparameter verwenden". Selbst wenn Sie könnten, werden die nachfolgenden Argumente in zB 'f0 (* arrayOf (), 0, 1, 2)' mit dem Inhalt des Spread-Arrays kombiniert, was einen anderen Fehler verursacht: "Das Integer-Literal nicht entsprechen dem erwarteten Typ Nothing ". – mfulton26