web-dev-qa-db-fra.com

Les cartes sont-elles passées par valeur ou par référence dans Go?

Les cartes sont-elles passées par valeur ou référence dans Go?

Il est toujours possible de définir une fonction comme suit, mais est-ce excessif?

func foo(dat *map[string]interface{}) {...}

Même question pour la valeur de retour. Dois-je renvoyer un pointeur sur la carte ou la renvoyer en tant que valeur? 

L'intention est bien sûr d'éviter une copie inutile des données. 

33
chmike

Dans ce fil, vous trouverez votre réponse:

Golang: Accéder à une carte en utilisant sa référence

Vous n'avez pas besoin d'utiliser un pointeur avec une carte.

Les types de carte sont des types de référence, comme des pointeurs ou des tranches [1]

Si vous aviez besoin de changer de session, vous pouvez utiliser un pointeur:

map[string]*Session

https://blog.golang.org/go-maps-in-action

32
Boris Le Méec

Voici quelques extraits de Si une carte n’est pas une variable de référence, c’est quoi? par Dave Chaney:

Une valeur de carte est un pointeur sur une structure runtime.hmap.

et conclusion:

Conclusion

Les cartes, comme les canaux, mais contrairement aux tranches, ne sont que des pointeurs vers l'exécution les types. Comme vous l'avez vu ci-dessus, une carte est simplement un pointeur sur un runtime.hmap structure.

Les cartes ont la même sémantique de pointeur que toute autre valeur de pointeur dans un Allez programme. Il n'y a pas de sauvegarde magique pour la réécriture de la syntaxe de la carte par le compilateur en appels de fonctions dans runtime/hmap.go.

Et un élément intéressant sur l'historique/l'explication de la syntaxe map:

Si les cartes sont des pointeurs, ne devraient-elles pas être une valeur * map [clé]?

C’est une bonne question que si les cartes sont des valeurs de pointeur, pourquoi le expression make (map [int] int) renvoie une valeur avec le type map [int] int . Ne devrait-il pas retourner un * map [int] int? Ian Taylor a récemment répondu ceci dans un golang-nuts thread1.

Au tout début, ce que nous appelons maintenant les cartes étaient écrits comme des pointeurs, alors vous avez écrit * map [int] int. Nous nous sommes éloignés de cela lorsque nous avons réalisé que personne n'a jamais écrit map sans écrire *map.

Renommer sans doute le type de * map [int] int à map [int] int, tout en prêtant à confusion car le type ne ressemble pas à un pointeur, était moins déroutant qu'un pointeur valeur en forme qui ne peut pas être déréférencée.

3
Akavall

Aucune carte n'est référencée par défaut.

    package main

    import "fmt"

    func mapToAnotherFunction(m map[string]int) {
        m["hello"] = 3
        m["world"] = 4
        m["new_Word"] = 5
    }

    // func mapToAnotherFunctionAsRef(m *map[string]int) {
    // m["hello"] = 30
    // m["world"] = 40
    // m["2ndFunction"] = 5
    // }

    func main() {
        m := make(map[string]int)
        m["hello"] = 1
        m["world"] = 2

        // Initial State
        for key, val := range m {
            fmt.Println(key, "=>", val)
        }

        fmt.Println("-----------------------")

        mapToAnotherFunction(m)
        // After Passing to the function as a pointer
        for key, val := range m {
            fmt.Println(key, "=>", val)
        }

        // Try Un Commenting This Line
        fmt.Println("-----------------------")

        // mapToAnotherFunctionAsRef(&m)
        // // After Passing to the function as a pointer
        // for key, val := range m {
        //  fmt.Println(key, "=>", val)
        // }

        // Outputs
        // prog.go:12:4: invalid operation: m["hello"] (type *map[string]int does not support indexing)
        // prog.go:13:4: invalid operation: m["world"] (type *map[string]int does not support indexing)
        // prog.go:14:4: invalid operation: m["2ndFunction"] (type *map[string]int does not support indexing)

    }

De Golang Blog- 

Les types de carte sont des types de référence, tels que les pointeurs ou les tranches, et la valeur de m ci-dessus est donc nulle; il ne pointe pas sur une carte initialisée. Une carte nil se comporte comme une carte vide lors de la lecture, mais une tentative d'écriture sur une carte nue provoquera une panique à l'exécution. ne fais pas ça. Pour initialiser une carte, utilisez la fonction make intégrée:

m = make(map[string]int)

Lien d'extrait de code Joue avec.

0
Md. Alamin Mahamud