Eu sempre vi os termos immutable
e os const
usei de forma intercambiável. No entanto, da minha (pequena) experiência, os dois diferem muito no 'contrato' que eles fazem no código:
Imutável torna o contrato que este objeto não será alterado, seja qual for (por exemplo, tuplas Python, seqüências de caracteres Java).
Const faz o contrato de que, no escopo desta variável, ela não será modificada (nenhuma promessa sobre o que outros threads podem fazer com o objeto apontado durante esse período, por exemplo, a palavra-chave C / C ++).
Obviamente, os dois não são equivalentes, a menos que o idioma seja de thread único (PHP) ou tenha um sistema de digitação linear ou de exclusividade (Clean, Mercury, ATS).
Primeiro, meu entendimento desses dois conceitos está correto?
Segundo, se há uma diferença, por que eles são quase exclusivamente usados de forma intercambiável?
fonte
const
não existe em todos os idiomas, e mutabilidade e imutabilidade não existem em todos os idiomas, portanto, tornar esse idioma agonístico não é aplicável. É específico da linguagem apenas onde esses conceitos se aplicam.Respostas:
Vou falar com C ++, onde essa diferença é mais relevante.
Como você notou corretamente, imutável significa que um objeto não pode ser alterado após a sua criação. É claro que essa criação pode ocorrer em tempo de execução, ou seja, um
const
objeto não é necessariamente uma constante em tempo de compilação. No C ++, um objeto é imutável se (1) e (2) ou (3) forem atendidos:Ele não possui membros declarados
mutable
que são alterados porconst
funções de membroÉ declarado
const
const
funções de membro não usamconst_cast
para remover aconst
qualificação, a fim de alterar qualquer membroNo entanto, você também pode considerar modificadores de acesso: se uma operação modificar internamente uma instância, mas não afetar o estado da instância observável por meio de sua interface pública, o objeto será "logicamente imutável".
Portanto, o C ++ fornece as ferramentas necessárias para criar objetos imutáveis, mas, como quase tudo no C ++, as ferramentas são minimamente suficientes e requerem diligência para realmente serem usadas. O estado de uma instância não está necessariamente confinado às variáveis de membro da instância - porque o C ++ não fornece uma maneira de impor transparência referencial, pode incluir também o estado global ou de classe.
const
também possui outra função no C ++: qualificar referências e ponteiros. Umaconst
referência pode se referir a um não-const
objeto. É legal (embora geralmente não seja necessário ou aconselhável) usarconst_cast
para alterar um objeto por meio de umaconst
referência, se e somente se esse objeto for declarado nãoconst
:E é claro que é um comportamento indefinido modificar um
const
objeto:fonte
Falando em Java, onde a palavra-chave "final" representa "const", considere:
Isso significa
someone
que NUNCA pode se referir a outro objeto Pessoa. Mas você ainda pode alterar os detalhes da pessoa que está sendo encaminhada. Por exemplosomeone.setMonthlySalary(10000);
Mas, se
someone
fosse um objeto "Imutável", um dos seguintes seria verdadeiro: (a) Você não teria um método chamadosetMonthlySalary
(b) Chamar setMonthlySalary sempre lançaria uma exceção comoUnsupportedOperationException
fonte
Objetos imutáveis são aqueles que não mudam de estado após a criação. Por exemplo;
Neste exemplo, o objeto myComplexStr é imutável, mas não constante, pois seu valor é calculado. E é imutável porque é uma string e possui uma propriedade de comprimento estático e não pode ser alterada.
Os objetos Const geralmente são usados para identificar algumas constantes reais cujos valores são conhecidos antes da compilação, como Pi, "USA", "StackOverflow.com", números de porta e assim por diante.
Nesta perspectiva, Const é diferente de Objetos imutáveis porque seus valores não são calculados pelo programa.
Mas se você estiver falando sobre a palavra-chave "const" em C ++, poderá dizer que "const" é usado para criar objetos imutáveis.
fonte
const
assim é um comportamento indefinido, não importa onde ele esteja alocado, IIRC. E o comportamento indefinido é pior do que qualquer erro específico garantido. Isso significa que você não usa mais o C ++ - o C ++ não oferece meios de alterar umconst
valor (exceto osmutable
membros, é claro, mas esse não é o seu ponto); portanto, no que diz respeito ao C ++, você não pode fazê-lo. O que implementações específicas permitem é outra questão inteiramente (e aposto que, se você compilar com otimizações, o truque que você executou não afetará as expressões posteriores,pi
porque foi substituído).Sim, mas sua segunda pergunta mostra que você não entende essas diferenças.
const
em C ++ é usado apenas para o nível de acesso (significa "somente leitura") , não para imutabilidade. Isso implica que o acesso em si é totalmente separado dos dados. Por exemplo, você pode manipular alguns dados e expô-los através de uma referência const. O acesso é somente leitura, mas os dados em si, pois todo o datam é mutável.const apenas garante limitações de acesso, enquanto a imutabilidade (como em D, por exemplo) não implica realmente nenhuma maneira de alterar os dados em qualquer estágio da vida do objeto .
Agora, você pode simular a imutabilidade no C ++, certificando-se de que alguns dados não possam ser acessados de outra maneira que não const e verifique se eles foram inicializados e não mais tocados. Mas isso não é uma garantia forte, pois linguagens como D oferecem quando você marca seus dados como imutáveis. A linguagem garante que não seja possível realizar nenhuma operação de modificação desses dados, enquanto em C ++ você ainda é potencialmente capaz de alterar os dados por meio da conversão e mutabilidade de const, se realmente necessário.
No final, não é o mesmo , pois não oferece as mesmas garantias.
fonte
Falando em JavaScript, as palavras-chave
const
eObject.freeze
const
aplica-se a ligaçõesvariables
. Ele cria uma ligação imutável, você não pode atribuir um novo valor a ela.Object.freeze
trabalha com valores de objetos. Torna um objeto imutável . Ou seja, você não pode alterar suas propriedades.fonte
Em C ++ eles são os mesmos. Embora você possa alterar um
const
objeto, se tiver sua localização na memória e a permissão do SO para gravar nessa memória.fonte
Em C, C ++ e linguagens relacionadas, também há uma diferença entre um objeto sendo const e sua referência ou ponteiro para o objeto sendo uma referência constante.
Se você tentar modificar um objeto constante, terá um comportamento indefinido. (Você pode tentar modificar um objeto constante, por exemplo, pegando seu endereço, convertendo o endereço em um ponteiro não const e, em seguida, usando esse ponteiro não const para modificar o objeto).
O ponteiro constante ou referência, por outro lado, apenas informa ao compilador que você não pode usar esse ponteiro ou referência para modificar o objeto. Você pode converter o ponteiro ou referência e tentar modificar o objeto. Se o objeto em si fosse constante, coisas ruins acontecerão. Se o objeto não fosse realmente constante, ele mudaria. Obviamente, isso pode confundir os usuários do seu código e possivelmente causar bugs.
Em C, se você usar uma string literal como "Hello", os cinco caracteres e os zero bytes à direita serão realmente constantes, mas você obterá um ponteiro não-const. É uma péssima idéia usar esse ponteiro não-const para alterar o objeto.
Em C, você pode ter um ponteiro "const restring". Isso significa que o objeto apontado é temporariamente constante. Se o objeto for modificado por qualquer meio enquanto o ponteiro "const restring" estiver no escopo, você terá um comportamento indefinido. Isso é mais forte que um ponteiro const, o que apenas impede que você altere um objeto por esse ponteiro.
fonte