
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 Typedans un paramètre elem. En d'autres termes, Go crée une variable elemavec 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
appends'attend à ce que le premier argument soit une tranche de type Typesuivie 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 Typequ'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
s1et s2le 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 acceptsait-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
appendn'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
getMultiplesavec un premier argument de factortype 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
makecré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 argspar 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
getMultiplescomme deuxième argument? Le compilateur signalera une erreur: dans l'argument,getMultiplesil ne peut pas être utilisés (type [] int)comme typeint. En effet, la tranche a un type qui[]int, getMultiplesattend 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
argsou 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
sont 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: