125 votes

Quel est l'intérêt d'avoir des pointeurs dans Go?

Je sais que les pointeurs dans Go permettent la mutation des arguments d'une fonction, mais cela n'aurait-il pas été plus simple s'ils adoptaient simplement des références (avec les qualificateurs const ou mutable appropriés). Nous avons maintenant des pointeurs et pour certains types intégrés, tels que les cartes et les canaux, un transfert implicite passe par référence.

Est-ce que je manque quelque chose ou est-ce que les pointeurs dans Go sont juste une complication inutile?

39voto

Adam Smith Points 2167

Les pointeurs sont utiles pour plusieurs raisons. Les pointeurs permettent de contrôler disposition de la mémoire (affecte l'efficacité de cache du PROCESSEUR). Allez on peut définir une structure où tous les membres sont dans la mémoire contiguë:

type Point struct {
  x, y int
}

type LineSegment struct {
  source, destination Point
}

Dans ce cas, l' Point des structures sont intégrés au sein de l' LineSegment struct. Mais vous ne pouvez pas toujours intégrer directement les données. Si vous voulez soutenir des structures telles que les arbres binaires ou liste liée, alors vous avez besoin à l'appui de une sorte de pointeur.

type TreeNode {
  value int
  left  *TreeNode
  right *TreeNode
}

Java, Python, etc n'ont pas ce problème car il ne vous permet pas d'intégrer des types de composé, donc il n'est pas nécessaire d'un point de vue syntaxique de différencier entre l'incorporation et de pointage.

Problèmes avec C# structs résolu avec les pointeurs

Une alternative possible pour accomplir la même chose est à différencier struct et class comme C#. Mais ce n'est pas sans problèmes non plus. Parce qu'il vous oblige à toujours faire de la valeur sémantique, même lorsque cela n'a pas de sens.

E. g. dire que j'ai une ligne de tableau de 4x4 matricies utilisés pour représenter les nœuds dans un graphe de scène ou quelque chose de similaires. J'ai pu pour qu'en C#, mais je ne pouvais pas passer entre accèdent en tant que valeur ou un pointeur. Si c'était un tableau de points je ne voudrais pas utiliser un pointeur. E. g:

// In this case we want to copy points on computation
var points [1024]Point
var q Point = calcSomePoint()

for p in range points {
   result := dotProduct(p, q)
   doStuff(result)
}

// We don't want to copy matricies each time we perform a computation because
// they are big, but we want them in contiguous memory
var matricies [1024]Matrix4x4
var n Matrix4x4 = caclSomeMatrix()

for m in range matricies {
   multiply(&n, &m)     // Avoid copying 2*4*4*8 = 256 bytes on each computation
}

Donc, en C# vous êtes toujours obligé d'envoyer struct autour de en les copiant. Cela peut facilement tuer la performance dans une application C# qui est pourquoi MS recommande structs pas de plus de 16 octets. Avec Go, puisqu'il prend en charge les pointeurs vous pouvez choisir exactement où vous voulez passer vos structures autour de l'utilisation des pointeurs et quand vous voulez les copier. Cela rend plus facile pour Aller au travail avec de grandes structures sans tuer la performance.

Personnalisé Allocateur De Mémoire

En utilisant les pointeurs vous pouvez également créer votre propre piscine allocateur (ce qui est très simplifié avec un grand nombre de vérifications retiré juste vous montrer 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
}

Échanger deux valeurs

Les pointeurs permet également de mettre en oeuvre swap. C'est de permuter les valeurs de deux variables:

func swap(a *int, b *int) {
   temp := *a
   *a = *b
   *b = temp
}

Conclusion

Java n'a jamais été pleinement en mesure de remplacer C++ pour la programmation de systèmes à des endroits tels que Google, en partie parce que la performance ne peut pas être réglée à la même étendre en raison du manque de capacité de contrôler disposition de la mémoire et de l'usage (le cache affecter les performances de manière significative). Aller a cherché à remplacer C++ dans de nombreux domaines et a donc besoin de l'appui des pointeurs.

35voto

Piotr Kochański Points 8162

J'aime beaucoup les exemples tirés de http://www.golang-book.com/8

 func zero(x int) {
    x = 0
}
func main() {
    x := 5
    zero(x)
    fmt.Println(x) // x is still 5
}
 

par opposition à

 func zero(xPtr *int) {
    *xPtr = 0
}
func main() {
    x := 5
    zero(&x)
    fmt.Println(x) // x is 0
}
 

33voto

peterSO Points 25725

Go est conçu pour être un laconique minimaliste de la langue. Il a donc commencé avec des valeurs et des pointeurs. Plus tard, par nécessité, d'autres types de référence (tranches, des cartes et des canaux) ont été ajoutés.


L'Aller Langage de Programmation : Langage de Conception FAQ : Pourquoi les cartes, les tranches, et les chaînes de références, tandis que les tableaux sont des valeurs?

"Il y a beaucoup d'histoire sur ce sujet. Dès le début, des cartes et des canaux ont été pour la syntaxe des pointeurs et il était impossible de déclarer ou de l'utilisation d'un non-pointeur d'instance. Aussi, nous avons eu du mal avec la façon dont les tableaux doivent travailler. Finalement, nous avons décidé que la stricte séparation des pointeurs et des valeurs fait la langue la plus difficile à utiliser. L'introduction de types de référence, y compris les tranches à gérer la référence forme de tableaux, pour régler ces questions. Les types de référence ajouter quelques regrettables de la complexité de la langue, mais ils ont un grand effet sur la facilité d'utilisation: Go est devenu plus productif, plus confortables langue quand ils ont été introduits."


Rapide compilation est l'un des principaux objectifs de la conception de la langue de programmation; qui a ses coûts. L'une des victimes semble être la capacité de marquer des variables (sauf pour la base de la compilation des constantes de temps) et de paramètres comme immuable. Il a été demandé, mais tourné vers le bas.


golang-noix : langage go. Des commentaires et des doutes.

"L'ajout de const pour le type de système de forces à apparaître un peu partout, et les forces de l'un à supprimer partout si quelque chose change. Alors qu'il y peut-être un certain avantage pour le marquage des objets immuables d'une certaine façon, nous n'avons pas pensez const type de qualificatif est de chemin à parcourir."

28voto

zildjohn01 Points 6173

Les références ne peuvent pas être réaffectées, contrairement aux pointeurs. Cela seul rend les pointeurs utiles dans de nombreuses situations où les références ne peuvent pas être utilisées.

-6voto

45g Points 35

"Les références ne peuvent pas être réaffectées, alors que les pointeurs le peuvent. [...]" zildjohn01

Pourquoi pas? Exemple Java:

     String s = "foo";
    s = "bar";
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X