J'ai souvent vu les termes immutable
et const
utilisé de manière interchangeable. Cependant, d'après ma (petite) expérience, les deux diffèrent beaucoup dans le «contrat» qu'ils font dans le code:
Immutable fait le contrat que cet objet ne changera pas (que ce soit par exemple des tuples Python, des chaînes Java).
Const fait le contrat que dans la portée de cette variable, elle ne sera pas modifiée (aucune promesse que ce soit sur ce que d'autres threads pourraient faire à l'objet pointé pendant cette période, par exemple le mot-clé C / C ++).
Évidemment, les deux ne sont pas équivalents, sauf si le langage est monothread (PHP), ou a un système de typage linéaire ou unique (Clean, Mercury, ATS).
Premièrement, ma compréhension de ces deux concepts est-elle correcte?
Deuxièmement, s'il y a une différence, pourquoi sont-ils presque exclusivement utilisés de manière interchangeable?
la source
const
n'existe pas dans toutes les langues, et la mutabilité et l'immuabilité n'existent pas dans toutes les langues, donc rendre ce langage agonistique n'est pas applicable. Il est spécifique au langage uniquement lorsque ces concepts s'appliquent.Réponses:
Je vais parler de C ++, où cette différence est la plus pertinente.
Comme vous le constatez correctement, immuable signifie qu'un objet ne peut pas changer du tout après sa création. Cette création peut bien sûr se produire au moment de l'exécution, c'est-à-dire qu'un
const
objet n'est pas nécessairement une constante au moment de la compilation. En C ++, un objet est immuable si (1) et (2) ou (3) sont respectés:Il n'a pas de membres déclarés
mutable
qui sont mutés parconst
les fonctions membresIl est déclaré
const
const
les fonctions membres n'utilisent pasconst_cast
pour supprimer laconst
qualification afin de muter des membresCependant, vous pouvez également envisager des modificateurs d'accès: si une opération mute en interne une instance, mais n'a aucun effet sur l'état de l'instance observable via son interface publique, alors l'objet est «logiquement immuable».
C ++ fournit donc les outils nécessaires pour créer des objets immuables, mais comme la plupart des éléments en C ++, les outils ne sont que très peu suffisants et nécessitent une diligence pour être réellement utilisés. L'état d'une instance n'est pas nécessairement limité aux variables membres de l'instance - car C ++ ne fournit pas un moyen d'imposer la transparence référentielle, il peut également inclure un état global ou de classe.
const
a également une autre fonction en C ++: qualifier les références et les pointeurs. Uneconst
référence peut faire référence à un non-const
objet. Il est légal (mais pas généralement nécessaire ou conseillé) d'utiliserconst_cast
pour muter un objet via uneconst
référence, si et seulement si cet objet est déclaré nonconst
:Et bien sûr, c'est un comportement indéfini de muter un
const
objet:la source
En parlant de Java où le mot-clé "final" représente "const", considérons:
Cela signifie que vous
someone
ne pouvez JAMAIS faire référence à un autre objet Personne. Mais, vous pouvez toujours modifier les détails de la personne référée. Par exemplesomeone.setMonthlySalary(10000);
Mais, s'il
someone
s'agissait d'un objet "immuable", l'une des conditions suivantes serait vraie: (a) Vous n'auriez pas de méthode nomméesetMonthlySalary
(b) L'appel à setMonthlySalary lèverait toujours une exception telle queUnsupportedOperationException
la source
Les objets immuables sont ceux qui ne changent pas d'état après leur création. Par exemple;
Dans cet exemple, l'objet myComplexStr est immuable mais pas constant car sa valeur est calculée. Et il est immuable car il s'agit d'une chaîne et a une propriété de longueur statique et ne peut pas changer.
Les objets const sont généralement utilisés pour identifier certaines constantes réelles dont les valeurs sont connues avant la compilation comme Pi, "USA", "StackOverflow.com", les numéros de port, etc.
De ce point de vue, Const est différent des objets immuables car leurs valeurs ne sont pas calculées par le programme.
Mais si vous parlez du mot clé "const" en C ++, vous pouvez dire que "const" est utilisé pour créer des objets immuables.
la source
const
semblable qui est un comportement indéfini, peu importe où il est alloué, IIRC. Et un comportement indéfini est pire que toute erreur spécifique garantie. Cela signifie que vous n'utilisez plus C ++ - C ++ ne fournit aucun moyen de modifier uneconst
valeur (sauf lesmutable
membres bien sûr, mais ce n'est pas votre point), donc en ce qui concerne C ++, vous ne pouvez pas le faire. Ce que les implémentations spécifiques autorisent est une tout autre affaire (et je parie que si vous compilez avec des optimisations, le coup que vous avez tiré n'affectera pas les expressions ultérieurespi
car il a été remplacé).Oui, mais votre deuxième question montre que vous ne comprenez pas ces différences.
const
en C ++ n'est utilisé que pour le niveau d'accès (cela signifie "en lecture seule") , pas pour l'immuabilité. Cela implique que l'accès lui-même est totalement séparé des données. Par exemple, vous pouvez manipuler certaines données puis les exposer via une référence const. L'accès est en lecture seule, mais les données elles-mêmes, car toutes les données sont modifiables.const ne garantit que les limitations d'accès, alors que l' immuabilité (comme dans D par exemple) n'implique vraiment aucun moyen de modifier les données à quelque stade que ce soit de la vie de l'objet .
Maintenant, vous pouvez simuler l'immuabilité en C ++ en vous assurant qu'il n'est pas possible d'accéder à certaines données autrement que const et en vous assurant qu'elles sont initialisées puis ne plus être touchées. Mais ce n'est pas une garantie solide car des langues comme D vous donnent lorsque vous marquez vos données comme immuables. Le langage s'assure qu'il n'est pas possible du tout d'effectuer une opération de modification de ces données, tandis qu'en C ++, vous êtes toujours potentiellement en mesure de modifier les données via la conversion de const et la mutabilité si vraiment nécessaire.
Au final, ce n'est pas du tout pareil car il n'offre pas du tout les mêmes garanties.
la source
En parlant de JavaScript, les mots clés
const
etObject.freeze
const
s'applique aux liaisonsvariables
. Il crée une liaison immuable, vous ne pouvez pas lui attribuer une nouvelle valeur.Object.freeze
fonctionne sur les valeurs des objets. Cela rend un objet immuable . À savoir, vous ne pouvez pas modifier ses propriétés.la source
En C ++, ce sont les mêmes. Bien que vous puissiez modifier un
const
objet si vous avez son emplacement en mémoire et l'autorisation du système d'exploitation pour écrire dans cette mémoire.la source
En C, C ++ et les langages apparentés, il existe également une différence entre un objet étant const et votre référence ou pointeur vers l'objet étant une référence constante.
Si vous essayez de modifier un objet constant, vous obtenez un comportement indéfini. (Vous pouvez essayer de modifier un objet constant par exemple en prenant son adresse, en convertissant l'adresse en un pointeur non const, puis en utilisant ce pointeur non const pour modifier l'objet).
Le pointeur ou la référence constante, d'autre part, indique simplement au compilateur que vous ne pouvez pas utiliser ce pointeur ou cette référence pour modifier l'objet. Vous pouvez caster le pointeur ou la référence et essayer de modifier l'objet. Si l'objet lui-même était constant, de mauvaises choses se produiront. Si l'objet n'était pas réellement constant, il changera. Bien sûr, cela peut dérouter les utilisateurs de votre code et éventuellement provoquer des bugs.
En C, si vous utilisez un littéral de chaîne comme "Bonjour", les cinq caractères et les zéro octets de fin sont en fait constants, mais vous obtenez un pointeur non const. Très mauvaise idée d'utiliser ce pointeur non constant pour changer l'objet.
En C, vous pouvez avoir un pointeur "const restrict". Cela signifie que l'objet pointé est temporairement constant. Si l'objet est modifié par tout moyen alors que le pointeur "const restrict" est dans la portée, vous obtenez un comportement indéfini. C'est plus fort qu'un pointeur const qui vous empêche seulement de changer un objet via ce pointeur.
la source