Que signifie immuable?


104

Si une chaîne est immuable, cela signifie-t-il que ... (supposons JavaScript)

var str = 'foo';

alert(str.substr(1)); // oo

alert(str); // foo

Cela signifie-t-il que lors de l'appel de méthodes sur une chaîne, il renverra la chaîne modifiée, mais ne changera pas la chaîne initiale?

Si la chaîne était mutable, cela signifie-t-il que le 2ème alert()reviendrait ooégalement?

Réponses:


105

Cela signifie qu'une fois que vous instanciez l'objet, vous ne pouvez pas modifier ses propriétés. Dans votre première alerte, vous ne changez pas foo. Vous créez une nouvelle chaîne. C'est pourquoi, dans votre deuxième alerte, il affichera "foo" au lieu de oo.

Cela signifie-t-il que lors de l'appel de méthodes sur une chaîne, il renverra la chaîne modifiée, mais ne changera pas la chaîne initiale?

Oui. Rien ne peut changer la chaîne une fois qu'elle est créée. Maintenant, cela ne signifie pas que vous ne pouvez pas affecter un nouvel objet chaîne à la strvariable. Vous ne pouvez tout simplement pas changer l'objet actuel auquel str fait référence.

Si la chaîne était mutable, cela signifie-t-il que la deuxième alerte () renverrait également oo?

Techniquement, non, car la méthode substring renvoie une nouvelle chaîne. Rendre un objet mutable ne changerait pas la méthode. Le rendre mutable signifie que techniquement, vous pouvez faire en sorte que la sous-chaîne change la chaîne d'origine au lieu d'en créer une nouvelle.


La même chaîne si elle est modifiée et attribuée, mettra à jour la chaîne var str = 'foo'; str = str.substr (1)); // oo alert (str); // oo
Ashwin G

Qu'en est-il du code ci-dessous. La valeur de la chaîne est maintenant modifiée. nom var = "Santosh"; console.log (nom.substr (0,2)); var name = "kumar" console.log (nom); Comment c'est toujours immuable
Santosh

97

À un niveau inférieur, l'immuabilité signifie que la mémoire dans laquelle la chaîne est stockée ne sera pas modifiée. Une fois que vous créez une chaîne "foo", de la mémoire est allouée pour stocker la valeur "foo". Cette mémoire ne sera pas altérée. Si vous modifiez la chaîne avec, par exemple, substr(1)une nouvelle chaîne est créée et une partie différente de la mémoire est allouée qui sera stockée "oo". Vous avez maintenant deux chaînes en mémoire, "foo"et "oo". Même si vous n'allez "foo"plus l' utiliser , il restera jusqu'à ce qu'il soit ramassé.

Une des raisons pour lesquelles les opérations de chaînes sont relativement coûteuses.


1
Les nombres sont également immuables.
RN Kushwaha

3
bonjour de 2015 !! «À un niveau inférieur, l'immuabilité signifie que la mémoire dans laquelle la chaîne est stockée ne sera pas modifiée.» --- c'est trop restrictif et ne sonne pas correctement. L'immuabilité ne concerne que l'espace utilisateur, la mémoire virtuelle peut être modifiée comme l'allocateur de mémoire le souhaite dès que les invariants de spécification de langue sont conservés.
zerkms

2
Cette réponse est plus logique que la réponse acceptée.
Ejaz Karim du

Mais je peux faire comme var str = 'foo'; je peux modifier via str = 'bar'. La valeur de str a été modifiée de cette façon, non?
Hacker

@ Hacker Non. Vous avez affecté une nouvelle chaîne à la variable pointant vers un nouvel emplacement en mémoire.
deceze

13

Immuable signifie ce qui ne peut pas être changé ou modifié.

Ainsi, lorsque vous attribuez une valeur à une chaîne, cette valeur est créée à partir de zéro au lieu d'être remplacée. Ainsi, chaque fois qu'une nouvelle valeur est affectée à la même chaîne, une copie est créée. Donc, en réalité, vous ne changez jamais la valeur d'origine.


9

Je ne suis pas certain de JavaScript, mais en Java, les chaînes franchissent une étape supplémentaire vers l'immuabilité, avec le "String Constant Pool". Les chaînes peuvent être construites avec des littéraux de chaîne ( "foo") ou avec un Stringconstructeur de classe. Les chaînes construites avec des littéraux de chaîne font partie du pool de constantes de chaîne, et le même littéral de chaîne sera toujours la même adresse mémoire du pool.

Exemple:

    String lit1 = "foo";
    String lit2 = "foo";
    String cons = new String("foo");

    System.out.println(lit1 == lit2);      // true
    System.out.println(lit1 == cons);      // false

    System.out.println(lit1.equals(cons)); // true

Dans ce qui précède, les deux lit1et lit2sont construits en utilisant le même littéral de chaîne, ils pointent donc vers la même adresse mémoire; lit1 == lit2résultats true, car ils sont exactement le même objet.

Cependant, consest construit à l'aide du constructeur de classe. Bien que le paramètre soit la même constante de chaîne, le constructeur alloue une nouvelle mémoire pour cons, ce qui signifie consn'est pas le même objet que lit1et lit2, bien qu'il contienne les mêmes données.

Bien sûr, étant donné que les trois chaînes contiennent toutes les mêmes données de caractères, l'utilisation de la equalsméthode retournera true.

(Les deux types de construction de chaînes sont immuables, bien sûr)


3

Immuable signifie que la valeur ne peut pas être modifiée. Une fois créé, un objet chaîne ne peut pas être modifié car il est immuable. Si vous demandez une sous-chaîne d'une chaîne, une nouvelle chaîne avec la partie demandée est créée.

L'utilisation de StringBuffer lors de la manipulation de chaînes rend l'opération plus efficace car StringBuffer stocke la chaîne dans un tableau de caractères avec des variables pour contenir la capacité du tableau de caractères et la longueur du tableau (String sous forme de tableau de caractères)


3

La définition de la mutabilité dans les manuels est susceptible de changer ou d'altérer. En programmation, nous utilisons le mot pour désigner des objets dont l'état est autorisé à changer avec le temps. Une valeur immuable est exactement le contraire - une fois qu'elle a été créée, elle ne peut jamais changer.

Si cela vous semble étrange, permettez-moi de vous rappeler que bon nombre des valeurs que nous utilisons tout le temps sont en fait immuables.

var statement = "I am an immutable value";
var otherStr = statement.slice(8, 17);

Je pense que personne ne sera surpris d'apprendre que la deuxième ligne ne change en rien la chaîne dans l'instruction. En fait, aucune méthode de chaîne ne change la chaîne sur laquelle elles opèrent, elles renvoient toutes de nouvelles chaînes. La raison en est que les chaînes sont immuables - elles ne peuvent pas changer, nous ne pouvons créer que de nouvelles chaînes.

Les chaînes ne sont pas les seules valeurs immuables intégrées à JavaScript. Les nombres sont également immuables. Pouvez-vous même imaginer un environnement où l'évaluation de l'expression 2 + 3 change la signification du nombre 2? Cela semble absurde, mais nous faisons cela avec nos objets et nos tableaux tout le temps.


2

Des chaînes aux piles ... un exemple simple à comprendre tiré du blog d' Eric Lippert :

Recherche de chemin à l'aide de A * dans C # 3.0, deuxième partie ...

Une pile mutable comme System.Collections.Generic.Stack n'est clairement pas adaptée. Nous voulons pouvoir emprunter un chemin existant et en créer de nouveaux pour tous les voisins de son dernier élément, mais pousser un nouveau nœud sur la pile standard modifie la pile. Nous devions faire des copies de la pile avant de la pousser, ce qui est ridicule car alors nous dupliquerions inutilement tout son contenu.

Les piles immuables n'ont pas ce problème. Pousser sur une pile immuable crée simplement une toute nouvelle pile qui se lie à l'ancienne comme sa queue. Puisque la pile est immuable, il n'y a aucun danger qu'un autre code arrive et dérange le contenu de la queue. Vous pouvez continuer à utiliser l'ancienne pile à votre guise.

Pour mieux comprendre l'immuabilité, lisez les articles d'Eric en commençant par celui-ci:

Immuabilité dans C #, première partie: types d'immuabilité


Cette citation contient une affirmation étrange - que la structure de données de la pile (en fait plusieurs piles avec partage de queue) est, dans son ensemble, une structure mutable - chaque push ou pop change la structure. Seuls les éléments individuels sont immuables. Et en principe, vous pourriez avoir la même structure mais avec des éléments mutables. Cela se produit dans certaines variantes de IIRC undoable union-find. L'immuabilité présente de gros avantages, mais le partage d'une partie ou de la totalité d'une structure de données en tant qu'optimisation est parfaitement possible avec des mutables. Même si vous voulez une immuabilité apparente pour d'autres références, vous pouvez toujours copier sur écriture si nécessaire.
Steve314

0

Une façon de comprendre ce concept est de regarder comment javascript traite tous les objets, par référence. Cela signifie que tous les objets sont modifiables après avoir été instanciés, cela signifie que vous pouvez ajouter un objet avec de nouvelles méthodes et propriétés. Cela est important car si vous voulez qu'un objet soit immuable, l'objet ne peut pas changer après avoir été instancié.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.