In Go kann eine Funktion nur Argumente der in der Parameterliste in der Funktionsdefinition angegebenen Typen akzeptieren. Die Sprachfunktion für verschiedene Parameter erschwert dies ein wenig, folgt jedoch genau definierten Regeln.
Die Funktionssignatur für fmt.Println
lautet:
func Println(a ...interface{}) (n int, err error)
Per der Sprache specific ,
Der letzte eingehende Parameter in einer Funktionssignatur kann einen Typ haben, dem ... vorangestellt ist. Eine Funktion mit einem solchen Parameter wird als variadisch bezeichnet und kann mit null oder mehr Argumenten für diesen Parameter aufgerufen werden.
Dies bedeutet, dass Sie Println
eine Liste von Argumenten vom interface{}
Typ übergeben können. Da alle Typen die leere Schnittstelle implementieren, können Sie eine Liste von Argumenten eines beliebigen Typs übergeben. So können Sie Println(1, "one", true)
beispielsweise fehlerfrei aufrufen . Siehe den Abschnitt "Übergeben von Argumenten an ... Parameter" der Sprachspezifikation:
Der übergebene Wert ist eine neue Schicht vom Typ [] T mit einem neuen zugrunde liegenden Array, dessen aufeinanderfolgende Elemente die tatsächlichen Argumente sind, die alle T zugewiesen werden müssen.
Der Teil, der Ihnen Probleme bereitet, steht direkt danach in der Spezifikation:
Wenn das endgültige Argument einem Slice-Typ [] T zugewiesen werden kann, kann es unverändert als Wert für einen ... T-Parameter übergeben werden, wenn auf das Argument ... folgt. In diesem Fall wird kein neues Slice erstellt.
flag.Args()
ist Typ []string
. Da T
in Println
ist interface{}
, []T
ist []interface{}
. Es stellt sich also die Frage, ob ein String-Slice-Wert einer Variablen vom Schnittstellen-Slice-Typ zugewiesen werden kann. Sie können dies einfach in Ihrem Go-Code testen, indem Sie eine Zuweisung versuchen, zum Beispiel:
s := []string{}
var i []interface{}
i = s
Wenn Sie eine solche Zuweisung versuchen, gibt der Compiler die folgende Fehlermeldung aus:
cannot use s (type []string) as type []interface {} in assignment
Und deshalb können Sie die Auslassungspunkte nach einem String-Slice nicht als Argument dafür verwenden fmt.Println
. Es ist kein Fehler, es funktioniert wie beabsichtigt.
Es gibt immer noch viele Möglichkeiten , können Sie drucken flag.Args()
mit Println
, wie
fmt.Println(flag.Args())
(wird [elem0 elem1 ...]
gemäß der Dokumentation des FMT-Pakets ausgegeben )
oder
fmt.Println(strings.Join(flag.Args(), ` `)
(wodurch die String-Slice-Elemente ausgegeben werden, die jeweils durch ein einzelnes Leerzeichen getrennt sind) Verwenden Sie beispielsweise die Join-Funktion im Strings-Paket mit einem String-Trennzeichen.
go run test.go some test flags
) herumgespielt , und es schien zu funktionieren, wennflags.Args()...
auf just gewechselt wurdeflag.Args()
(Ausgabe ist[some test flags]
, gefolgt von der neuen Zeile; schien auch mit der Registrierung tatsächlicher Flags zu funktionieren).