Differenza tra immutabile e costante

27

Ho spesso visto i termini immutable e const usati in modo intercambiabile. Tuttavia, dalla mia (piccola) esperienza, i due differiscono molto nel "contratto" che fanno nel codice:

Immutable rende il contratto che questo oggetto non cambierà, qualunque sia (ad esempio tuple Python, stringhe Java).

Const rende il contratto che nell'ambito di questa variabile non verrà modificato (nessuna promessa su ciò che altri thread potrebbero fare all'oggetto puntato durante questo periodo, ad esempio il C / C ++ parola chiave).

Ovviamente, i due non sono equivalenti, a meno che il linguaggio non sia a thread singolo (PHP), o abbia un sistema di tipizzazione lineare o uniquness (Clean, Mercury, ATS).

In primo luogo, la mia comprensione di questi due concetti è corretta?

In secondo luogo, se c'è una differenza, perché sono quasi esclusivamente usati in modo intercambiabile?

    
posta K.Steff 22.05.2012 - 01:10
fonte

7 risposte

13

Parlerò con C ++, dove questa differenza è più rilevante.

Come si nota correttamente, immutable significa che un oggetto non può cambiare affatto dopo la sua creazione. Questa creazione può naturalmente verificarsi in fase di esecuzione, ad esempio, un oggetto const non è necessariamente una costante in fase di compilazione. In C ++, un oggetto è immutabile se (1) e uno (2) o (3) sono soddisfatti:

  1. Non ha membri dichiarati mutable che sono mutati da const funzioni membro

  2. È dichiarato const

  3. Le funzioni membro
  4. const non utilizzano const_cast per rimuovere la qualifica const al fine di mutare i membri

Tuttavia, potresti anche considerare i modificatori di accesso: se un'operazione esegue la mutua di un'istanza internamente, ma non ha alcun effetto sullo stato dell'istanza osservabile attraverso la sua interfaccia pubblica, l'oggetto è "logicamente immutabile".

Quindi C ++ fornisce gli strumenti necessari per creare oggetti immutabili, ma come la maggior parte di tutto in C ++, gli strumenti sono solo minimamente sufficienti e richiedono diligenza per l'uso effettivo. Lo stato di un'istanza non è necessariamente limitato alle variabili membro di istanza, poiché il C ++ non fornisce un modo per applicare la trasparenza referenziale, ma può anche includere lo stato globale o di classe.

const ha anche un'altra funzione in C ++: per qualificare riferimenti e puntatori. Un riferimento const può riferirsi a un oggetto% nonconst. È legale (anche se non generalmente necessario o consigliabile) usare const_cast per mutare un oggetto attraverso un riferimento const , se e solo se quell'oggetto è dichiarato non- const :

int        i = 4;         // Non-const object.
const int* p = &i;        // const pointer.

*const_cast<int*>(p) = 5; // Legal.

E ovviamente è un comportamento non definito per mutare un oggetto const :

const int  i = 4;         // const object.
const int* p = &i;        // const pointer.

*const_cast<int*>(p) = 5; // Illegal.
    
risposta data 22.05.2012 - 05:16
fonte
18

Parlando per Java, dove la parola chiave "final" rappresenta "const", prendi in considerazione:

final Person someone = new Person();

Questo significa che someone non può MAI fare riferimento a un altro oggetto Person. Ma puoi ancora cambiare i dettagli della persona che viene indirizzata. Per esempio. someone.setMonthlySalary(10000);

Tuttavia, se someone era un oggetto "Immutabile", uno dei seguenti sarebbe vero: (a) Non avresti un metodo chiamato setMonthlySalary (b) Chiamare setMonthlySalary genererebbe sempre un'eccezione come UnsupportedOperationException

    
risposta data 22.05.2012 - 04:26
fonte
10

Gli oggetti immutabili sono quelli che non cambiano stato dopo averlo creato. Ad esempio;

string prefix = "Pre";
string postfix = "Post";
string myComplexStr = prefix + postfix;

In questo esempio l'oggetto myComplexStr è immutabile ma non costante perché viene calcolato il suo valore. Ed è immutabile perché è una stringa e ha una proprietà di lunghezza statica e non può cambiare.

Gli oggetti Const sono generalmente usati per identificare alcune costanti reali i cui valori sono noti prima della compilazione come Pi, "USA", "StackOverflow.com", numeri di porta e così via.

Da questa prospettiva, Const è diverso dagli oggetti Immutabili perché i loro valori non sono calcolati dal programma.

Ma se parli di parola chiave "const" in C ++, puoi dire che "const" è usato per creare oggetti immutabili.

    
risposta data 22.05.2012 - 02:38
fonte
7

First, is my understanding of these two concepts correct?

Sì, ma la tua seconda domanda mostra che non capisci queste differenze.

Second, if there is a difference, why are they almost exclusively used interchangeably?

const in C ++ viene utilizzato solo per il livello di accesso (significa "sola lettura") , non per l'immutabilità. Implica che l'accesso stesso sia totalmente separato dai dati. Ad esempio è possibile manipolare alcuni dati e quindi esporli attraverso un riferimento const. L'accesso è di sola lettura, ma i dati stessi, dato che tutto il datam è modificabile.

const garantisce solo le limitazioni di accesso, mentre l'immutabilità (come in D per esempio) non implica in realtà alcun modo per modificare i dati in qualsiasi fase della vita dell'oggetto .

Ora, è possibile simulare l'immutabilità in C ++ assicurandosi che alcuni dati non siano accessibili in qualsiasi altro modo rispetto a const e assicurarsi che sia inizializzato e quindi non più toccato. Ma questa non è una garanzia strong come le lingue come D ti danno quando contrassegni i tuoi dati come immutabili. Il linguaggio fa in modo che non sia possibile eseguire alcuna operazione che modifichi quei dati, mentre in C ++ sei ancora potenzialmente in grado di cambiare i dati attraverso la costellazione e la mutabilità se davvero necessario.

Alla fine, non è affatto lo stesso in quanto non offre affatto le stesse garanzie.

    
risposta data 22.05.2012 - 04:09
fonte
3

A proposito di JavaScript, le parole chiave const e Object.freeze

const si applica a binding variables . Crea un legame immutabile, non puoi assegnargli un nuovo valore.

Object.freeze funziona sui valori degli oggetti. Rende un oggetto immutable . Vale a dire, non puoi cambiare le sue proprietà.

    
risposta data 12.11.2015 - 07:18
fonte
0

In C ++ sono uguali. Sebbene tu possa modificare un oggetto const se hai la sua posizione in memoria e l'autorizzazione del sistema operativo per scrivere in quella memoria.

    
risposta data 22.05.2012 - 01:19
fonte
0

In C, C ++ e linguaggi correlati, c'è anche una differenza tra un oggetto const e il tuo riferimento o puntatore all'oggetto che è un riferimento costante.

Se si tenta di modificare un oggetto costante si ottiene un comportamento indefinito. (Puoi provare per modificare un oggetto costante, ad esempio prendendo il suo indirizzo, gettando l'indirizzo su un puntatore non-const e quindi usando quel puntatore non-const per modificare l'oggetto).

Il puntatore o riferimento costante d'altra parte dice semplicemente al compilatore che non puoi usare questo puntatore o riferimento per modificare l'oggetto. Puoi lanciare il puntatore o riferimento e provare a modificare l'oggetto. Se l'oggetto stesso fosse costante, accadranno cose brutte. Se l'oggetto non fosse effettivamente costante, cambierà. Questo ovviamente potrebbe confondere gli utenti del tuo codice e molto probabilmente causare bug.

In C, se si utilizza una stringa letterale come "Hello", i cinque caratteri e i byte zero finali sono effettivamente costanti, ma si ottiene un puntatore non const. Pessima idea usare quel puntatore non-const per cambiare l'oggetto.

In C, puoi avere un puntatore "const restrict". Ciò significa che l'oggetto puntato è temporaneamente costante. Se l'oggetto viene modificato in qualsiasi modo mentre il puntatore "const restrict" è in ambito, si ottiene un comportamento non definito. Questo è più strong di un puntatore const che ti impedisce solo di cambiare un oggetto attraverso questo puntatore.

    
risposta data 12.11.2015 - 11:34
fonte

Leggi altre domande sui tag