Apprenez GoLang en tant que nouvelle compétence linguistique. Deuxième partie : danser avec la concurrence et les pointeurs.
Certains points forts d'Effective Go reflètent sa philosophie de conception.
Méthode
Pointeur vs valeur
L'implémentation de Go sur la méthode Write est illustrée ci-dessous. Une chose doit être mentionnée. Nous lions la méthode Write avec le type ByteSlice afin que la fonction réceptrice puisse directement utiliser la méthode Write. Nous utilisons le pointeur plutôt que la valeur car, en utilisant le pointeur, nous pouvons directement remplacer la valeur de l'appelant.
type ByteSlice []byte
func (p *ByteSlice) Write(data []byte) (n int, err error) {
slice := *p
l := len(slice)
if l + len(data) > cap(slice) { // reallocate
// Allocate double what's needed, for future growth.
newSlice := make([]byte, (l+len(data))*2)
// The copy function is predeclared and works for any slice type.
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:l+len(data)]
copy(slice[l:], data)
*p = slice
return len(data), nil
}
var b ByteSlice
fmt.Fprintf(&b, "This hour has %d days\n", 7)
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
Concurrence
Partager par communication
La concurrence est un vaste sujet. GoLang a quelques points forts sur la concurrence. Il existe un slogan pour décrire le modèle de communication simultanée GoLang.
Ne communiquez pas en partageant la mémoire, partagez plutôt la mémoire en communiquant.
Chaque programmeur sait qu'il existe un exemple classique d'utilisation de mutex pour accéder à une variable partagée afin que chaque thread ait la même valeur de cette variable à un moment donné. GoLang a choisi une approche différente. Au lieu de verrouiller la variable de partition, elle partitionne avec différents canaux. Une seule goroutine a accès à cette valeur à un moment donné. Vous pouvez considérer le contrôle de concurrence GoLang comme un pipeline Unix. Il s'agit d'une valeur atomique unique passant par le pipeline pour exécution, et aucune synchronisation n'est nécessaire.
Goroutines
Les goroutines sont des fonctions qui s'exécutent en même temps que d'autres goroutines dans le même espace d'adressage. Si une goroutine est bloquée, cela n'affecte pas l'exécution des autres goroutines.
Les littéraux de fonction sont utiles pour l'invocation de goroutine. Les littéraux de fonction sont des fermetures . La variable référencée par la fonction vivra tant que la fonction est active.
func Announce(message string, delay time.Duration) {
go func() {
time.Sleep(delay)
fmt.Println(message)
}() // Note the parentheses - must call the function.
}
Le canal est une combinaison de communication et de synchronisation qui garantit que deux goroutines sont en bon état.
Une goroutine pour trier la liste est illustrée ci-dessous. Une autre routine consiste à faire autre chose. Le canal est garanti leurs états en utilisant la communication entre deux goroutines.
c := make(chan int) // Allocate a channel.
// Start the sort in a goroutine; when it completes, signal on the channel.
go func() {
list.Sort()
c <- 1 // Send a signal; value does not matter.
}()
doSomethingForAWhile()
<-c // Wait for sort to finish; discard sent value.
Dans cet article, nous avons discuté de deux fonctionnalités importantes de GoLang. 1. Comment GoLang utilise des références et des pointeurs pour obtenir un contrôle flexible à l'intérieur de la méthode 2. Comment GoLang gère les demandes de concurrence à l'aide de goroutines et de canaux. Dans le prochain article, nous parlerons davantage du mécanisme de récupération de place de Go. S'il vous plaît restez à l'écoute.