Quels types sont mutables et immuables dans la Langue Google Go?

dans Google Go, j'ai lu que les chaînes sont immuables, ok mais sont des int? Quels sont les autres types? En tant que programmeur un peu plus âgé, je préfère la mutabilité même si je connais les avantages de l'immutabilité, je préfère vivre dangereusement.

Savoir quels types sont mutables ou immuable serait très utile.


mise à jour, ce qui me préoccupe le plus est les questions pratiques selon le type étant mutable ou immuable. Comme dans L'exemple typique de Java, si vous créez une chaîne dans une boucle et boucle pour 10.000 fois, vous obtiendrez 10.000 chaînes créées qui sont ensuite ordures collectées. Cela a été en fait un problème sérieux dans un projet dans une entreprise où j'ai travaillé.

la question Est, Est-ce que L'immuabilité de Go dans certains cas cause le même problème?

il affecte la façon dont vous devriez traiter le var. (ou je suppose qu'il n').


mise à jour encore une fois, je suis également préoccupé par d'autres préoccupations d'ordre pratique. Savoir que quelque chose est immuable signifie que je peux écrire du code qui est parallèle et mises à jour à une référence de l'objet ne doit pas mettre à jour les autres références. Mais parfois je veux faire des choses dangereuses, je veux la mutabilité.

ce sont les conséquences de la mutabilité par rapport à l'immuabilité et affectent la façon dont je peux écrire le code.

26
demandé sur Phil 2011-11-05 07:54:48

6 réponses

Ne vous inquiétez pas: Allez vous permettra de tirer dans le pied si vous voulez vraiment :-)

Aller n'est pas comme Erlang, qui pourrait être ce que vous obtenez à la question.

x := 1
x = 2

alloue une variable, x, avec une valeur de 1, puis réassigne à 2 -- aucune mémoire supplémentaire est attribué ici.

comme vous le constatez, les chaînes de caractères sont immuables, donc faire une manipulation de chaîne de caractères peut conduire à faire des copies. Si vous trouvez que vous vous voulez faire des modifications en place aux données de caractères, vous voudrez probablement opérer sur les variables de []byte via le bytes paquet.

le post de Russ Cox à ce sujet devrait répondre à la plupart de vos questions sur les structures de données de base: http://research.swtch.com/2009/11/go-data-structures.html

comme d'autres commentateurs l'ont noté, vous voudrez examiner la sémantique de la valeur des fonctions de Go -- elles pourraient être un peu surprenantes au début.

si vous avez la fonction suivante:

func (t MyType) myFunc() {
    // do something to set a field in t
}

et que vous appelez dans votre code

myVar.myFunc()

vous pourriez être surpris de voir que cela ne fait pas ce que vous voulez parce que le t qui est vu dans le myFunc() est vraiment un copiermyVar.

mais, les suivants :

func (t *myType) myFunc() {
    // do something to set a field in t
}

parce que la fonction a une copie du pointeur et peut accéder à la structure sous-jacente via cette pointeur.

30
répondu robothor 2011-11-05 17:12:41

À mon avis, il faut d'abord séparer les deux concepts:

  • entiers comme objets mathématiques (c'est-à-dire: valeurs)

  • variables de type int

Alors la réponse est: les variables entières sont mutables, les valeurs entières sont immuables.

cette vue est compatible avec la spécification Go qui stipule que les chaînes sont immuables. De toute évidence, une chaîne de caractères variable est mutable.

les Variables (en tant que concept) dans Go sont au moins:

  • variables nommées (telles que:var i int)
  • variables accessibles via des pointeurs

Mutable Aller des objets:

  • tableaux et tranches
  • cartes
  • canaux
  • fermetures qui capturent au moins une variable de la portée extérieure

Immuable Go objets:

  • interfaces
  • booléens, valeurs numériques (y compris les valeurs de type int)
  • chaînes de caractères
  • les pointeurs
  • pointeurs de fonction, et fermetures qui peuvent être réduits à des pointeurs de fonction
  • les structures ayant un seul champ

objets qui certaines personnes peuvent considérer mutable, tandis que d'autres personnes puissent les considérer immuable:

  • les structures ayant plusieurs les champs
9
répondu 2011-11-05 15:20:07

Oui, le mot immuable apparaît exactement une fois dans go spec. Et c'est lors de la discussion type string. Je pense que vous devriez regarder cela de plus du double des points de vue de l' Cessibilité et adressabilité. Par exemple, Go vous interdira de rebobiner la variable à une valeur différente d'un type avec des propriétés non exposées, évidemment. Un peu comme en C++ pour les classes ne fournissant pas de constructeur de copie, mais en Go Pimpl se sent beaucoup moins maladroit, digne de la goroutines' partager en communiquant de la philosophie.

2
répondu ypb 2011-11-05 05:35:12

pour un int, ça n'a pas vraiment de sens de parler de mutabilité, parce que, quels sont les "composants" d'un int? Vous changez un int en lui assignant un tout nouveau int, mais l'assignation ne compte pas comme "Mutant".

il y a un certain lien entre les questions de la mutabilité et les types de référence par rapport aux types de valeurs. Sémantiquement, il n'y a pas de différence entre un type de référence immuable et un type de valeur. Pourquoi? Supposons que l'int soit en fait un pointeur vers un objet immuable (i.e. *InternalIntObject sans fonctions pour changer InternalIntObject). Une fois que vous assignez un tel pointeur à une variable, il représentera toujours la même valeur entière (ne peut pas être changée par d'autres qui partagent le même objet) puisque l'objet est immuable. C'est le même comportement qu'un entier de type valeur. Vous pouvez assigner des ints par opérateur de cession; de même vous pouvez assigner ces pointeurs par cession; le résultat serait le même: la variable assignée représente le même nombre entier que ce à quoi elle a été assignée. La seule différence serait la comparaison et les opérateurs arithmétiques devraient être redéfinis pour dé-référence le pointeur de calculer le résultat.

2
répondu newacct 2011-11-07 06:11:14

votre préoccupation semble être plus une question de répartition que d'immuabilité. L'immutabilité a certainement une incidence sur l'attribution en rendant impossible la réutilisation de la mémoire. Un compilateur intelligent pourrait réutiliser n'importe quelle mémoire" immuable " dont l'adresse ne s'échappe pas.

outre les chaînes, soyez prudent avec les interfaces. Tout ce qui dépasse la taille des mots devra être affecté à l'interface (mises à part les optimisations). Aussi, les variables déclarées dans un corps de boucle dont les adresses la fuite, y compris par une fermeture, devra être attribuée à chaque fois à travers la boucle. Dans le cas contraire, une affectation n'est qu'une affectation. La valeur est simplement copiée dans la mémoire représentée par la variable.

si vous utilisez make ou new dans une boucle, ou n'importe quel littéral qui produit une référence, l'allocation devra se produire (encore une fois, sous réserve d'optimisation).

fondamentalement, tout se résume à essayer de réutiliser la mémoire là où vous le pouvez, et espérer que le compilateur le fasse pour toi Quand tu ne peux pas, si ça a un sens de le faire.

1
répondu SteveMcQwark 2011-11-06 05:11:57

C'est de me donner la même adresse à chaque fois, donc peut-être les ints sont mutables.

package main

import "fmt"

func main() {
var i int
i = 5
fmt.Println(&i)
i = 6
fmt.Println(&i)
var k = 7
i = k
fmt.Println(&i)
}
-3
répondu Phil 2011-11-05 06:01:32