Variable Argumentlisten
Das Schlüsselwort
varargerzeugt eine flexibel dimensionierte Argumentliste.
In Listen haben wir listOf() eingeführt, das eine beliebige Anzahl von Parametern akzeptiert und eine Liste erzeugt:
// Varargs/ListOf.kt
import atomictest.eq
fun main() {
listOf(1) eq "[1]"
listOf("a", "b") eq "[a, b]"
}
Mit dem Schlüsselwort vararg können Sie eine Funktion definieren, die eine beliebige Anzahl von Argumenten annimmt, genau wie listOf(). vararg ist die Abkürzung für variable Argumentliste:
// Varargs/VariableArgList.kt
package varargs
fun v(s: String, vararg d: Double) {}
fun main() {
v("abc", 1.0, 2.0)
v("def", 1.0, 2.0, 3.0, 4.0)
v("ghi", 1.0, 2.0, 3.0, 4.0, 5.0, 6.0)
}
Eine Funktionsdefinition kann nur einen Parameter als vararg angeben. Obwohl es möglich ist, ein beliebiges Element in der Parameterliste als vararg anzugeben, ist es normalerweise am einfachsten, dies für das letzte zu tun.
vararg ermöglicht es Ihnen, eine beliebige Anzahl (einschließlich null) von Argumenten zu übergeben. Alle Argumente müssen vom angegebenen Typ sein. Auf vararg-Argumente wird mit dem Parameternamen zugegriffen, der zu einem Array wird:
// Varargs/VarargSum.kt
package varargs
import atomictest.eq
fun sum(vararg numbers: Int): Int {
var total = 0
for (n in numbers) {
total += n
}
return total
}
fun main() {
sum(13, 27, 44) eq 84
sum(1, 3, 5, 7, 9, 11) eq 36
sum() eq 0
}
Obwohl Arrays und Lists ähnlich aussehen, sind sie unterschiedlich implementiert — List ist eine reguläre Bibliotheksklasse, während Array spezielle Unterstützung auf niedriger Ebene hat. Array stammt aus der Anforderung von Kotlin, mit anderen Sprachen, insbesondere Java, kompatibel zu sein.
Im täglichen Programmieren verwenden Sie eine List, wenn Sie eine einfache Sequenz benötigen. Verwenden Sie Arrays nur, wenn eine Drittanbieter-API ein Array erfordert oder wenn Sie mit varargs arbeiten.
In den meisten Fällen können Sie einfach ignorieren, dass vararg ein Array erzeugt, und es behandeln, als ob es eine List wäre:
// Varargs/VarargLikeList.kt
package varargs
import atomictest.eq
fun evaluate(vararg ints: Int) =
"Size: ${ints.size}\n" +
"Sum: ${ints.sum()}\n" +
"Average: ${ints.average()}"
fun main() {
evaluate(10, -3, 8, 1, 9) eq """
Size: 5
Sum: 25
Average: 5.0
"""
}
Sie können ein Array von Elementen überall dort übergeben, wo ein vararg akzeptiert wird. Um ein Array zu erstellen, verwenden Sie arrayOf() auf die gleiche Weise wie listOf(). Ein Array ist immer veränderbar. Um ein Array in eine Folge von Argumenten (nicht nur ein einzelnes Element des Typs Array) zu konvertieren, verwenden Sie den Spread-Operator, *:
// Varargs/SpreadOperator.kt
import varargs.sum
import atomictest.eq
fun main() {
val array = intArrayOf(4, 5)
sum(1, 2, 3, *array, 6) eq 21 // [1]
// Doesn't compile:
// sum(1, 2, 3, array, 6)
val list = listOf(9, 10, 11)
sum(*list.toIntArray()) eq 30 // [2]
}
Wenn Sie ein Array von primitiven Typen (wie Int, Double oder Boolean) wie im obigen Beispiel übergeben, muss die Array-Erstellungsfunktion spezifisch typisiert sein. Wenn Sie arrayOf(4, 5) anstelle von intArrayOf(4, 5) verwenden, wird Zeile [1] einen Fehler erzeugen, der besagt, dass der abgeleitete Typ ist Array<Int>, aber IntArray wurde erwartet.
Der Streuoperator funktioniert nur mit Arrays. Wenn Sie eine List haben, die Sie als Folge von Argumenten übergeben möchten, konvertieren Sie sie zuerst in ein Array und wenden Sie dann den Streuoperator an, wie in [2]. Da das Ergebnis ein Array eines primitiven Typs ist, müssen wir erneut die spezifische Konvertierungsfunktion toIntArray() verwenden.
Der Streuoperator ist besonders hilfreich, wenn Sie vararg-Argumente an eine andere Funktion übergeben müssen, die ebenfalls varargs erwartet:
// Varargs/TwoFunctionsWithVarargs.kt
package varargs
import atomictest.eq
fun first(vararg numbers: Int): String {
var result = ""
for (i in numbers) {
result += "[$i]"
}
return result
}
fun second(vararg numbers: Int) =
first(*numbers)
fun main() {
second(7, 9, 32) eq "[7][9][32]"
}
Kommandozeilenargumente
Beim Aufrufen eines Programms auf der Kommandozeile können Sie ihm eine variable Anzahl von Argumenten übergeben. Um Kommandozeilenargumente zu erfassen, müssen Sie main() einen bestimmten Parameter bereitstellen:
// Varargs/MainArgs.kt
fun main(args: Array<String>) {
for (a in args) {
println(a)
}
}
Der Parameter wird traditionell args genannt (obwohl Sie ihn beliebig nennen können), und der Typ für args kann nur Array<String> (Array von String) sein.
Wenn Sie IntelliJ IDEA verwenden, können Sie Programmargumente über die Bearbeitung der entsprechenden “Run-Konfiguration” übergeben, wie im letzten Übungsteil für dieses Atom gezeigt.
Sie können auch den kotlinc-Compiler verwenden, um ein Befehlszeilenprogramm zu erstellen. Wenn kotlinc nicht auf Ihrem Computer vorhanden ist, folgen Sie den Anweisungen auf der Kotlin-Hauptseite. Nachdem Sie den Code für MainArgs.kt eingegeben und gespeichert haben, geben Sie Folgendes an einer Eingabeaufforderung ein:
kotlinc MainArgs.kt
Sie geben die command-line arguments nach dem program invocation ein, so:
kotlin MainArgsKt hamster 42 3.14159
Sie werden diese Ausgabe sehen:
hamster
42
3.14159
Wenn Sie einen String-Parameter in einen spezifischen Typ umwandeln möchten, stellt Kotlin Konvertierungsfunktionen bereit, wie zum Beispiel toInt() für die Umwandlung in einen Int und toFloat() für die Umwandlung in einen Float. Bei der Verwendung dieser Funktionen wird angenommen, dass die Kommandozeilenargumente in einer bestimmten Reihenfolge erscheinen. Hier erwartet das Programm einen String, gefolgt von etwas, das in einen Int umwandelbar ist, gefolgt von etwas, das in einen Float umwandelbar ist:
// Varargs/MainArgConversion.kt
fun main(args: Array<String>) {
if (args.size < 3) return
val first = args[0]
val second = args[1].toInt()
val third = args[2].toFloat()
println("$first $second $third")
}
Die erste Zeile in main() beendet das Programm, wenn nicht genügend Argumente vorhanden sind. Wenn Sie nichts angeben, das in ein Int und ein Float umgewandelt werden kann, als zweites und drittes Kommandozeilenargument, werden Sie Laufzeitfehler sehen (versuchen Sie es, um die Fehler zu sehen).
Kompilieren und führen Sie MainArgConversion.kt mit denselben Kommandozeilenargumenten aus, die wir zuvor verwendet haben, und Sie werden sehen:
hamster 42 3.14159
Übungen und Lösungen finden Sie unter www.AtomicKotlin.com.