web-dev-qa-db-fra.com

Que signifie immuable?

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 retournera la chaîne modifiée, mais ne changera pas la chaîne initiale?

Si la chaîne était mutable, cela signifie-t-il que la 2e alert() renverrait également oo?

101
alex

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 retournera 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 variable str. Vous ne pouvez tout simplement pas modifier l'objet actuel auquel str fait référence.

Si la chaîne était mutable, cela signifie-t-il que la 2e alerte () retournerait également oo?

Techniquement, non, car la méthode de sous-chaîne renvoie une nouvelle chaîne. Rendre un objet mutable ne changerait pas la méthode. La 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.

103
kemiller2002

À 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 avez créé une chaîne "foo", De la mémoire est allouée pour stocker la valeur "foo". Cette mémoire ne sera pas modifié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 stockera "oo". Vous avez maintenant deux chaînes en mémoire, "foo" Et "oo". Même si vous n'utilisez plus "foo", Il restera jusqu'à ce qu'il soit récupéré.

L'une des raisons pour lesquelles les opérations de chaîne sont relativement coûteuses.

97
deceze

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 modifiez jamais la valeur d'origine.

13
SoftwareGeek

Je ne suis pas certain de JavaScript, mais en Java, les chaînes font un pas 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 constructeur de classe String. 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 lit1 et lit2 sont construits en utilisant le même littéral de chaîne, donc ils pointent vers la même adresse mémoire; lit1 == lit2 donne true, car ce sont exactement le même objet.

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

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

(Les deux types de construction de cordes sont immuables, bien sûr)

9
Brian S

Immuable signifie que la valeur ne peut pas être modifiée. Une fois créé, un objet chaîne ne peut pas être modifié comme étant 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 Strings 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
Nataraj

La définition de mutabilité dans les manuels est susceptible ou susceptible d'être modifiée ou altérée. En programmation, nous utilisons le mot pour désigner les objets dont l'état peut changer au fil du temps. Une valeur immuable est exactement le contraire - une fois 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 modifie en rien la chaîne en déclaration. En fait, aucune méthode de chaîne ne modifie 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 que créer de nouvelles chaînes.

Les chaînes ne sont pas les seules valeurs immuables intégrées à JavaScript. Les nombres sont immuables aussi. 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.

3
ahmed khattab

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

Recherche de chemin en utilisant A * dans C # 3.0, deuxième partie ...

Une pile modifiable comme System.Collections.Generic.Stack n'est clairement pas appropriée. Nous voulons pouvoir prendre 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 idiot car nous dupliquerions alors tout son contenu inutilement.

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. Étant donné que la pile est immuable, il n'y a aucun danger qu'un autre code arrive et salisse le contenu de la queue. Vous pouvez continuer à utiliser l'ancienne pile à votre guise.

Pour approfondir la compréhension de l'immuabilité, lisez les articles d'Eric en commençant par celui-ci:

Immuabilité en C # Première partie: Types d'immuabilité

2
Leniel Maccaferri

Une façon de comprendre ce concept est de regarder comment javascript traite tous les objets, ce qui est par référence. Cela signifie que tous les objets sont mutables 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é.

0
Rick