Petits pièges en Go
Lors des meetups Golang Paris, nous avons vu quelques trucs et astuces et pièges courant en Go. Voici un compte-rendu et bouts de codes.
Les meetups Golang Paris sont un moment privilégiés pour faire du code, avoir du retour d'expérience bref monter en compétence et rencontrer des gens sympas. N'hésitez pas à vous inscrire et à venir:
https://www.meetup.com/fr-FR/Golang-Paris/
et aussi à consulter la page github également:
Utilisation de Go routines et assignation de variables
Nous allons montrer un piège qui est arrivé sur un exemple plus complexe à la base mais qui peut se résumer ainsi:
- Nous partons d'un bout de code simple qui boucle et affiche le contenu de la variable "i" dans une Go routine
package main
import (
"fmt"
)
func main() {
fmt.Println("Demo on goroutines seq")
for i := 0; i < 10; i++ {
go func() {
fmt.Println("Val i: %d", i)
}()
}
}
Si vous executez ce code : https://play.golang.org/p/PyMsrChN-ZD
vous verrez uniquement `Demo on goroutines seq` d'affiché : le programme effectue la boucle et sort avant qu'il n'ait le temps de lancer les routines.
- Ajoutons un sleep à la fin.
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Demo on goroutines seq")
for i := 0; i < 10; i++ {
go func() {
fmt.Printf("Val i: %d\n", i)
}()
}
time.Sleep(500 * time.Millisecond)
}
et maintenant, que devons nous voir: 10 lignes avec ` Val i: 10 `.
Encore une fois, les routines sont lancées une fois que la boucle est terminée. Les routines sont créées avec une référence sur la variable "i" et non pas une copie.
- Une façon de corriger cela est de passer en paramètre la variable "i" à la routine:
https://play.golang.org/p/BiSCQtXQ6wl
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Demo on goroutines seq")
for i := 0; i < 10; i++ {
go func(cpt int) {
fmt.Printf("Val i: %d\n", cpt)
}(i)
}
time.Sleep(500 * time.Millisecond)
}
et vous voila avec une boucle qui affiche les chiffres de 0 à 9, mais en parallèle!
Les slices et leur valeur sous-jacente
Regardez l'exemple de code disponible sur le repo de Meetup Golang Paris:
Sans revenir sur une description poussée des slices, ceux-ci peuvent être liés à un tableau sous-jacent. Si vous ne changez pas la capacité du slice, il y a la même référence que le tableau mais dans le cas d'une nouvelle allocation, vous changez d'emplacement.
Ce cas est à garder en tête car il peut être difficile à débugger et se comporter comme "un bug aléatoire".