Les pointeurs sont utiles pour plusieurs raisons. Les pointeurs permettent de contrôler la disposition de la mémoire (affecte l'efficacité du cache du processeur). Dans Go, nous pouvons définir une structure où tous les membres sont en mémoire contiguë:
type Point struct {
x, y int
}
type LineSegment struct {
source, destination Point
}
Dans ce cas, les Point
structures sont intégrées dans la LineSegment
structure. Mais vous ne pouvez pas toujours intégrer directement des données. Si vous souhaitez prendre en charge des structures telles que des arbres binaires ou des listes chaînées, vous devez prendre en charge une sorte de pointeur.
type TreeNode {
value int
left *TreeNode
right *TreeNode
}
Java, Python, etc. n'ont pas ce problème car ils ne vous permettent pas d'incorporer des types composites, il n'est donc pas nécessaire de différencier syntaxiquement entre l'incorporation et le pointage.
Problèmes avec les structures Swift / C # résolus avec les pointeurs Go
Une alternative possible pour accomplir la même chose est de faire la différence entre struct
et class
comme le fait C # et Swift. Mais cela a des limites. Bien que vous puissiez généralement spécifier qu'une fonction prend une structure comme inout
paramètre pour éviter de copier la structure, elle ne vous permet pas de stocker des références (pointeurs) vers des structures. Cela signifie que vous ne pouvez jamais traiter une structure comme un type de référence lorsque vous trouvez cela utile, par exemple pour créer un allocateur de pool (voir ci-dessous).
Allocateur de mémoire personnalisé
En utilisant des pointeurs, vous pouvez également créer votre propre allocateur de pool (ceci est très simplifié avec de nombreuses vérifications supprimées pour ne montrer que le principe):
type TreeNode {
value int
left *TreeNode
right *TreeNode
nextFreeNode *TreeNode; // For memory allocation
}
var pool [1024]TreeNode
var firstFreeNode *TreeNode = &pool[0]
func poolAlloc() *TreeNode {
node := firstFreeNode
firstFreeNode = firstFreeNode.nextFreeNode
return node
}
func freeNode(node *TreeNode) {
node.nextFreeNode = firstFreeNode
firstFreeNode = node
}
Échangez deux valeurs
Les pointeurs vous permettent également de mettre en œuvre swap
. C'est permuter les valeurs de deux variables:
func swap(a *int, b *int) {
temp := *a
*a = *b
*b = temp
}
Conclusion
Java n'a jamais été en mesure de remplacer complètement C ++ pour la programmation de systèmes dans des endroits tels que Google, en partie parce que les performances ne peuvent pas être réglées de la même manière en raison du manque de capacité à contrôler la disposition et l'utilisation de la mémoire (les erreurs de cache affectent considérablement les performances). Go a pour objectif de remplacer le C ++ dans de nombreux domaines et doit donc prendre en charge les pointeurs.