Je suis nouveau dans la programmation orientée objet, et un concept qui m'a pris un certain temps à saisir est l'immuabilité. Je pense que l'ampoule s'est éteinte hier soir mais je veux vérifier:
Lorsque je rencontre des déclarations selon lesquelles un objet immuable ne peut pas être modifié, je suis perplexe car je peux, par exemple, faire ce qui suit:
NSString *myName = @"Bob";
myName = @"Mike";
Là, je viens de changer myName, de type immuable NSString. Mon problème est que le mot «objet» peut faire référence à l'objet physique en mémoire ou à l'abstraction «monNom». L'ancienne définition s'applique au concept d'immuabilité.
Quant à la variable, une définition plus claire (pour moi) de l'immuabilité est que le valeur d'un objet immuable ne peut être modifiée qu'en changeant également son emplacement dans la mémoire, c'est-à-dire sa référence (également connue sous le nom de pointeur).
Est-ce correct ou suis-je toujours perdu dans les bois?
la source
NSString
, c'est un " pointeur vers etNSString
", qui n'est pas immuable. Je ne sais rien de C objectif, mais je devine dans votre exemple qui@"Mike"
crée une nouvelle instance deNSString
et en lui attribuant au pointeur ,myName
. Vous n'avez donc pas changé l'objet quimyName
pointait, juste ce qu'il pointait.Réponses:
Il semble que vous vous dirigiez dans la bonne direction, mais vous ne l'avez pas encore tout à fait. C'est faux:
Dans votre extrait de code, il
myName
n'est pas de type immuableNSString
, il est de type mutableNSString*
(pointeur vers NSString). Il semble que la chose clé qui vous manque est de comprendre qu'un pointeur est juste une autre valeur , et qu'il a une vie complètement distincte de la chose qu'il pointe (ou des choses, si vous le changez en cours de vie).Vous dites:
C'est faux. Un objet ne possède les pointeurs qui pointent vers elle, ni l'emplacement de la mémoire d'un objet contrôlé ou autrement affecté par des pointeurs vers elle.
Ainsi, les deux
NSString
objets de votre exemple (@"Bob"
et@"Mike"
) sont complètement séparés de lamyName
variable. Ils sont également complètement séparés les uns des autres. Lorsque vous changezmyName
pour pointer vers@"Mike"
au lieu de pointer vers@"Bob"
, vous ne modifiez pas lesNSString
objets.Pour être complet, je noterai que les ramasse-miettes rendent cela plus complexe dans la mesure où les modifications apportées aux pointeurs peuvent affecter les objets vers lesquels ils pointent (ed). Cependant, il s'agit d'un détail d'implémentation qui ne devrait pas affecter le comportement observable du code.
la source
Vous êtes perdu aux mots. L'immuabilité signifie: Tant que vous ne modifiez pas la variable, elle «contiendra» toujours la même valeur, peu importe ce que vous faites avec les autres variables.
Contre-exemple en C (un peu simplifié, en supposant une architecture qui le permet):
Désormais, un "ne contient plus" (c'est-à-dire pointe vers) la chaîne "Hello World", mais c'est "Yello World" à la place.
Dans les langages où les chaînes sont immuables, comme Java et (EDIT: sûr) C #, vous ne pouvez pas faire cela. En aucune façon. Cela signifie que chaque partie du programme peut conserver en toute sécurité une référence à la chaîne et compter que son contenu ne change jamais; sinon, ils devraient créer une copie juste pour être sûr.
Mais la variable est toujours modifiable. Vous pouvez le laisser pointer vers un autre objet. C'est juste que l'objet lui-même ne changera pas derrière votre dos.
la source
unsafe
code.Vous confondez des variables avec des objets. Les variables peuvent être utilisées pour stocker des références à des objets, mais ce ne sont PAS des objets. Ce sont des objets qui sont immuables, pas des variables, vous pouvez donc changer la variable d'un objet à un autre, mais vous ne pouvez pas changer les attributs de l'objet s'il est immuable.
Considérez l'objet comme un voisin bruyant et ivre. S'il est raisonnable (mutable), vous pourriez peut-être frapper à sa porte et le convertir à un style de vie où il ne fait pas autant de bruit. Mais s'il est immuable, votre seul changement est d'espérer que quelqu'un d'autre emménage!
la source
Une variable n'est pas un objet. Une variable est un nom, qui fait référence à un objet (ou plus généralement à une valeur).
Par exemple, "le gardien de but" est un nom que nous utilisons pour désigner l'objet (la personne) chargé de défendre le but. Mais si je remplace cette personne par une autre (parce que la première est blessée ou autre), la nouvelle personne est maintenant appelée le "gardien de but".
L'instruction d'affectation est ce qui rend les variables mutables (certains langages, comme Haskell ne l'ont pas et utilisent en fait des variables immuables). Il vous permet de redéfinir la signification d'un nom et ainsi de réaffecter la valeur.
Désormais, les objets eux - mêmes peuvent être immuables. Il y a quelques milliers d'années, on aurait pu penser que les diamants étaient immuables. Peu importe ce que vous avez fait avec un diamant, vous ne pouvez pas le modifier. Que vous l'appeliez waggawooga (traduit vaguement par "la plus grande pierre brillante de notre tribu") ou que vous ayez cessé de l'appeler ainsi (parce que vous en avez trouvé une plus grosse), le diamant est resté le même. En revanche, le morceau de bois que vous avez utilisé pour sculpter des images drôles avec votre waggawooga n'est pas resté le même. Cela s'est révélé mutable. Même s'il avait toujours le même nom.
Les variables et les valeurs peuvent être immuables (indépendamment). Dans ce cas, ce sont les objets qui sont immuables. Une fois que vous avez construit un
NSString
, vous ne pouvez plus le modifier. Vous pouvez l'appeler par des noms et le faire circuler, mais il restera le même. Contrairement à cela,NSMutableString
peut être modifié après la création, par exemple en appelant lasetString
méthode.la source
Je pense que vous vous sentez perdu, car vous mélangez deux concepts: l'objet lui-même et le nom de variable lié à cet objet.
Les objets immuables ne peuvent pas être modifiés. Période. Cependant, le nom de variable (symbole) lié à un objet immuable peut être modifié pour être lié à un autre objet immuable.
En d'autres termes, ce que vous avez fait dans ces deux lignes était:
myName
à cet objetmyName
à cet objetla source
Votre type n'est pas un
NSString
, c'est un " pointeur vers unNSString
", qui n'est pas immuable. Je ne sais rien de l'objectif C, mais je suppose que dans votre exemple, il@"Mike"
s'agit de créer une nouvelle instance deNSString
et de l'attribuer au pointeurmyName
. Donc , vous n'avez pas changé l'objet quimyName
a été pointé à, juste ce qu'il pointait.la source
Voici un exemple d'objet mutable: un tableau de
char
en C:Je peux changer le contenu de
str
mon contenu (tant qu'il ne dépasse pas 10 caractères). Pour qu'il soit reconnu comme une chaîne par les fonctions de bibliothèque de chaînes C, il doit y avoir un 0 à la fin, afin qu'il puisse contenir des chaînes jusqu'à 9 caractères:und so weiter .
Comparez cela avec un objet chaîne en Java:
L' instance de chaîne (le bloc de mémoire qui contient les caractères «H», «e», «l», «l» et «o») ne peut pas être modifiée; Je ne peux pas modifier le contenu de cette chaîne. Lorsque vous écrivez quelque chose comme
vous n'ajoutez pas "World" à la fin de l'instance "Hello"; vous créez une nouvelle instance , copiez "Hello World" et mettez
foo
à jour pour faire référence à cette nouvelle instance de chaîne.foo
ne contient pas lui-même l'instance de chaîne; il se réfère uniquement à cette instance (similaire à un pointeur en C ou Obj-C), d'où pourquoi des types comme String sont appelés types de référence.la source