En Go, une fonction ne peut accepter que les arguments des types spécifiés dans la liste des paramètres de la définition de la fonction. La fonction de langage des paramètres variadiques complique un peu les choses, mais elle suit des règles bien définies.
La signature de la fonction pour fmt.Println
est :
func Println(a ...interface{}) (n int, err error)
Par le spécification de la langue ,
Le dernier paramètre entrant dans la signature d'une fonction peut avoir un type préfixé par ..... Une fonction avec un tel paramètre est dite variadique et peut être invoquée avec zéro ou plusieurs arguments pour ce paramètre.
Cela signifie que vous pouvez passer Println
une liste d'arguments de interface{}
type. Puisque tous les types implémentent l'interface empty, vous pouvez passer une liste d'arguments de n'importe quel type, c'est ainsi que vous pouvez appeler Println(1, "one", true)
par exemple, sans erreur. Voir le Section "Passer des arguments aux paramètres ...". de la spécification du langage :
la valeur passée est une nouvelle tranche de type []T avec un nouveau tableau sous-jacent dont les éléments successifs sont les arguments réels, qui doivent tous être assignables à T.
La partie qui vous pose problème se trouve juste après dans les spécifications :
Si l'argument final est assignable à une tranche de type []T, il peut être transmis inchangé comme valeur pour un paramètre ...T si l'argument est suivi de ..... Dans ce cas, aucune nouvelle tranche n'est créée.
flag.Args()
est le type []string
. Puisque T
en Println
es interface{}
, []T
es []interface{}
. La question se résume donc à savoir si une valeur de tranche de chaîne est assignable à une variable de type tranche d'interface. Vous pouvez facilement tester cela dans votre code go en tentant une affectation, par exemple :
s := []string{}
var i []interface{}
i = s
Si vous tentez une telle affectation, le compilateur affichera ce message d'erreur :
cannot use s (type []string) as type []interface {} in assignment
Et c'est pourquoi vous ne pouvez pas utiliser le point de suspension après une tranche de chaîne de caractères comme argument à fmt.Println
. Ce n'est pas un bug, il fonctionne comme prévu.
Il existe encore de nombreuses façons d'imprimer flag.Args()
con Println
comme
fmt.Println(flag.Args())
(qui sera affiché comme [elem0 elem1 ...]
par documentation du paquet fmt )
o
fmt.Println(strings.Join(flag.Args(), ` `)
(qui produira les éléments de la tranche de chaîne, chacun étant séparé par un espace) en utilisant la fonction Join du paquet strings avec un séparateur de chaîne, par exemple.