L'équipe Mail.ru Cloud Solutions atraduit un article sur les fonctions variadiques de Go. Son auteur explique en quoi les fonctions variadiques diffèrent des fonctions ordinaires et comment les créer.
Qu'est-ce qu'une fonction variadique
Fonction - un morceau de code conçu pour effectuer une tâche spécifique. La fonction reçoit un ou plusieurs arguments et renvoie un ou plusieurs résultats.
Les fonctions variantes sont les mêmes que les fonctions régulières, mais elles peuvent prendre un nombre infini ou variable d'arguments.
func f(elem ...Type)
Voici à quoi ressemble la syntaxe typique des fonctions variadiques. L'opérateur
...
, également connu sous le nom d'opérateur de boxe, indique à Go de stocker tous les arguments de type Type
dans un paramètre elem
. En d'autres termes, Go crée une variable elem
avec un type []Type
, c'est-à-dire une tranche. Et tous les arguments passés à la fonction sont stockés dans la tranche elem
.
Voyons un exemple de fonction
append()
.
append([]Type, args, arg2, argsN)
La fonction
append
s'attend à ce que le premier argument soit une tranche de type Type
suivie d'un nombre arbitraire d'arguments. Mais comment ajouter une tranche s2
à une tranche s1
?
Il découle de la définition de la fonction
append()
que nous ne pouvons pas lui passer deux tranches - il n'y a Type
qu'un seul argument de type . Par conséquent, nous utilisons l'opérateur unboxing ...
pour décompresser la tranche en une série d'arguments. Ils peuvent ensuite être passés à la fonction append
.
append(s1, s2...)
...
désignent à la fois l'opérateur d'emballage et l'opérateur de déballage. L'opérateur de déballage apparaît toujours après le nom de la variable.
Dans notre exemple, les tranches
s1
et s2
le même type. Nous connaissons généralement les paramètres d'une fonction et le nombre d'arguments qu'elle prend. Comment une fonction accept
sait-elle combien de paramètres lui ont été passés?
Si vous regardez la déclaration de fonction
append
, vous pouvez voir l'expression elems ...Type
. Il regroupe tous les arguments, en commençant par le second, dans une tranche elems
.
func append(slice []Type, elems ...Type) []Type
Seul le dernier argument d'une déclaration de fonction peut être variadique.
Par conséquent, le premier argument de la fonction
append
n'est qu'une tranche, car elle est définie comme une tranche. Tous les arguments suivants sont regroupés dans un seul argument nommé elems
.
Voyons maintenant comment créer votre propre fonction variadique.
Comment créer une fonction variadique
Comme mentionné ci-dessus, une fonction variadique est une fonction régulière qui prend un nombre variable d'arguments. Pour ce faire, vous devez utiliser l'opérateur de boxe
...Type
.
Écrivons une fonction
getMultiples
avec un premier argument de factor
type int
(facteur de multiplication) et un nombre variable d'arguments de type supplémentaires int
. Ils seront emballés dans une tranche args
.
Utilisez pour
make
créer une tranche vide, elle a la même taille que la tranche args
. À l'aide d'une boucle for range
, multipliez les éléments de tranche args
par factor
. Nous mettons le résultat dans une nouvelle tranche vide multiples
, que nous renverrons à la suite de la fonction.
func getMultiples(factor int, args ...int) []int {
multiples := make([]int, len(args))
for index, val := range args {
multiples[index] = val * factor
}
return multiples
}
C'est une fonction très simple, appliquez-la à l'intérieur d'un bloc
main()
.
func main() {
s := []int{10, 20, 30}
mult1 := getMultiples(2, s...)
mult2 := getMultiples(3, 1, 2, 3, 4)
fmt.Println(mult1)
fmt.Println(mult2)
}
https://play.go.org/p/BgU6H9orhrn
Que se passe-t-il si, dans l'exemple ci-dessus, vous passez la tranche s à la fonction
getMultiples
comme deuxième argument? Le compilateur signalera une erreur: dans l'argument,getMultiples
il ne peut pas être utilisés (type [] int)
comme typeint
. En effet, la tranche a un type qui[]int, getMultiples
attend des paramètres deint
.
Comment une tranche est passée à une fonction variadique
Slice est une référence à un tableau. Alors, que se passe-t-il lorsque vous passez une tranche à une fonction variadique à l'aide de l'opérateur unboxing? Go crée-t-il une nouvelle tranche
args
ou utilise- t-il une ancienne tranche s
?
Comme nous n'avons pas d'outils de comparaison
args == s
, nous devons changer la tranche args
. Ensuite, nous découvrons si la tranche d'origine a changé s
.
https://play.go.org/p/fbNgVGu6JZO
Dans l'exemple ci-dessus, nous avons légèrement modifié la fonction
getMultiples
. Et au lieu de créer une nouvelle tranche, nous affectons les résultats du calcul aux éléments de la tranche args
, en remplaçant les éléments entrants par les éléments multipliés.
En conséquence, nous voyons que les valeurs de la tranche d'origine
s
ont changé. Si vous passez des arguments à la fonction variadic via l'opérateur de déballage, alors Go utilise des références au tableau de données sous-jacent à l'original pour créer une nouvelle tranche. Veillez à ne pas vous tromper, sinon les données d'origine changeront à la suite des calculs.
Bonne chance!
Quoi d'autre à lire: