Maison  >  Article  >  développement back-end  >  La différence entre les pointeurs et les valeurs sur les méthodes

La différence entre les pointeurs et les valeurs sur les méthodes

Linda Hamilton
Linda Hamiltonoriginal
2024-11-26 01:35:15345parcourir

The difference between pointers and values on methods

Lors de l'écriture de méthodes dans Go, l'une des décisions clés est de savoir s'il faut transmettre une structure par valeur ou par pointeur. Ce choix peut avoir un impact sur les performances, le comportement du code et l'allocation de mémoire. Dans cet article, nous explorerons cette différence avec un exemple pratique et comprendrons quand chaque approche est plus appropriée.

Commençons par une petite structure et deux méthodes : une où la structure est passée par valeur et une autre par pointeur.

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

// Method with struct passed by value
func (p Person) CelebrateBirthdayValue() {
    p.Age++
}

// Method with struct passed by pointer
func (p *Person) CelebrateBirthdayPointer() {
    p.Age++
}

func main() {
    person := Person{Name: "Alice", Age: 30}

    // Passing by value
    person.CelebrateBirthdayValue()
    fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30

    // Passing by pointer
    person.CelebrateBirthdayPointer()
    fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31
}

Différence entre valeur et pointeur

Lorsque nous passons une structure par valeur à une méthode, Go crée une copie de la structure. Toute modification apportée à la structure à l'intérieur de la méthode n'affectera pas la structure d'origine car nous travaillons avec une copie indépendante.

D'un autre côté, lorsque nous passons une structure par pointeur, nous transmettons l'adresse mémoire de la structure d'origine. Cela signifie que toute modification apportée à la structure à l'intérieur de la méthode modifiera directement la structure d'origine puisque nous manipulons la même instance.

En résumé :

  • Par valeur : La méthode reçoit une copie de la structure, créant un nouvel espace mémoire.

  • Par pointeur : La méthode reçoit l'adresse mémoire de la structure d'origine, pointant vers le même espace mémoire.

Tas

Lorsqu'une structure est passée par valeur, la copie est allouée sur la pile, ce qui est généralement rapide et efficace. Cependant, si la structure est volumineuse, la copie peut consommer une quantité importante de mémoire de pile.

Lorsqu'une structure est passée par un pointeur, le pointeur lui-même est alloué sur la pile, mais la structure d'origine peut être allouée sur le tas, surtout si elle a été créée à l'aide de new, make ou capturée par une fonction anonyme.

L'allocation de tas est plus coûteuse en termes de temps d'allocation et de garbage collection, mais permet une manipulation efficace de grandes quantités de données sans copier la structure entière.

Quand utiliser chaque approche

Par valeur

Passer des structures par valeur est utile lorsque :

  • Vous voulez vous assurer que la structure d'origine n'est pas modifiée.
  • La structure est petite et sa copie n'a pas d'impact significatif sur les performances.
  • La méthode lit simplement les données sans avoir besoin de modifier l'état interne.

Exemple :

func (p Person) GetName() string {
    return p.Name
}

Ici, GetName lit uniquement le champ Name et renvoie une chaîne sans modifier l'état de la structure.

Par pointeur

Passer des structures par pointeur est bénéfique lorsque :

  • Vous devez modifier la structure d'origine.
  • La structure est volumineuse et la copie de ses données serait coûteuse en termes de mémoire et de performances.
  • Vous souhaitez éviter les copies inutiles pour améliorer l'efficacité du code.

Exemple :

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

// Method with struct passed by value
func (p Person) CelebrateBirthdayValue() {
    p.Age++
}

// Method with struct passed by pointer
func (p *Person) CelebrateBirthdayPointer() {
    p.Age++
}

func main() {
    person := Person{Name: "Alice", Age: 30}

    // Passing by value
    person.CelebrateBirthdayValue()
    fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30

    // Passing by pointer
    person.CelebrateBirthdayPointer()
    fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31
}

Dans ce cas, UpdateName modifie directement le champ Name de la structure d'origine, ce qui est plus efficace que de créer une copie.

Conclusion

Décider de transmettre une structure par valeur ou par pointeur lors de l'écriture de méthodes dans Go est un choix important qui peut affecter les performances, le comportement du code et l'allocation de mémoire.

Le passage par valeur est utile pour garantir l'immuabilité de la structure au sein de la méthode, tandis que le passage par pointeur est essentiel pour modifier la structure d'origine et optimiser les performances lorsque vous travaillez avec des structures plus grandes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn