O que significa imutável?

103

Se uma string é imutável, isso significa que .... (vamos supor que o JavaScript)

var str = 'foo';

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

alert(str); // foo

Isso significa que, ao chamar métodos em uma string, ele retornará a string modificada, mas não mudará a string inicial?

Se a string fosse mutável, isso significa que a segunda alert()também retornaria oo?

alex
fonte

Respostas:

104

Isso significa que, depois de instanciar o objeto, você não pode alterar suas propriedades. Em seu primeiro alerta, você não está mudando foo. Você está criando uma nova string. É por isso que em seu segundo alerta ele mostrará "foo" em vez de oo.

Isso significa que, ao chamar métodos em uma string, ele retornará a string modificada, mas não mudará a string inicial?

Sim. Nada pode alterar a string depois de criada. Agora, isso não significa que você não pode atribuir um novo objeto string para a strvariável. Você simplesmente não pode alterar o objeto atual que faz referência a str.

Se a string fosse mutável, isso significa que o segundo alerta () retornaria oo também?

Tecnicamente, não, porque o método substring retorna uma nova string. Tornar um objeto mutável não mudaria o método. Torná-lo mutável significa que, tecnicamente, você pode fazer com que a substring altere a string original em vez de criar uma nova.

kemiller2002
fonte
A mesma string, se modificada e atribuída, atualizará a string var str = 'foo'; str = str.substr (1)); // oo alert (str); // oo
Ashwin G
E o código abaixo. O valor da string foi alterado agora. var name = "Santosh"; console.log (name.substr (0,2)); var name = "kumar" console.log (nome); Como ainda é imutável
Santosh
97

Em um nível inferior, a imutabilidade significa que a memória em que a string está armazenada não será modificada. Depois de criar uma string "foo", parte da memória é alocada para armazenar o valor "foo". Esta memória não será alterada. Se você modificar a string com, digamos, substr(1)uma nova string é criada e uma parte diferente da memória é alocada para armazenar "oo". Agora você tem duas strings na memória "foo"e "oo". Mesmo se você não for usar "foo"mais, ele permanecerá por aqui até ser coletado no lixo.

Uma razão pela qual as operações de string são comparativamente caras.

deceze
fonte
1
Os números também são imutáveis.
RN Kushwaha
3
olá de 2015 !! "Em um nível inferior, imutabilidade significa que a memória em que a string está armazenada não será modificada." --- isso é muito restritivo e não soa bem. A imutabilidade diz respeito apenas ao terreno do usuário, a memória virtual pode ser alterada conforme o alocador de memória quiser, assim que as invariáveis ​​da especificação da linguagem forem mantidas.
zerkms
2
Essa resposta é mais lógica do que a resposta aceita.
Ejaz Karim
Mas posso fazer como var str = 'foo'; posso modificar via str = 'bar'. O valor str foi modificado dessa forma, certo?
Hacker de
@Hacker Não. Você atribuiu uma nova string à variável que aponta para um novo local na memória.
deceze
13

Imutável significa aquilo que não pode ser alterado ou modificado.

Portanto, quando você atribui um valor a uma string, esse valor é criado do zero, em vez de ser substituído. Portanto, toda vez que um novo valor é atribuído à mesma string, uma cópia é criada. Então, na realidade, você nunca está mudando o valor original.

SoftwareGeek
fonte
9

Não tenho certeza sobre JavaScript, mas em Java, as strings dão um passo adicional para a imutabilidade, com o "String Constant Pool". Strings podem ser construídas com literais de string ( "foo") ou com um Stringconstrutor de classe. Strings construídos com literais de string fazem parte do String Constant Pool, e o mesmo string literal sempre será o mesmo endereço de memória do pool.

Exemplo:

    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

Acima, ambos lit1e lit2são construídos usando o mesmo literal de string, então eles estão apontando para o mesmo endereço de memória; lit1 == lit2resulta em true, porque eles são exatamente o mesmo objeto.

No entanto, consé construído usando o construtor de classe. Embora o parâmetro seja a mesma constante de string, o construtor aloca nova memória para cons, o significado consnão é o mesmo objeto que lit1e lit2, apesar de conter os mesmos dados.

Obviamente, como todas as três strings contêm os mesmos dados de caractere, o uso do equalsmétodo retornará true.

(Ambos os tipos de construção de string são imutáveis, é claro)

Brian S
fonte
3

Imutável significa que o valor não pode ser alterado. Uma vez criado, um objeto string não pode ser modificado como seu imutável. Se você solicitar uma substring de uma string, uma nova String com a parte solicitada é criada.

Usar StringBuffer enquanto manipula Strings torna a operação mais eficiente, pois StringBuffer armazena a string em uma matriz de caracteres com variáveis ​​para manter a capacidade da matriz de caracteres e o comprimento da matriz (String em uma forma de matriz de char)

Nataraj
fonte
3

A definição do livro de texto de mutabilidade é responsável ou sujeita a mudanças ou alterações. Na programação, usamos a palavra para significar objetos cujo estado pode mudar com o tempo. Um valor imutável é exatamente o oposto - depois de criado, ele nunca pode mudar.

Se isso parece estranho, gostaria de lembrar que muitos dos valores que usamos o tempo todo são, na verdade, imutáveis.

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

Acho que ninguém ficará surpreso ao saber que a segunda linha de forma alguma altera a string na instrução. Na verdade, nenhum método de string altera a string em que operam, todos eles retornam novas strings. A razão é que as strings são imutáveis ​​- elas não podem mudar, só podemos fazer novas strings.

Strings não são os únicos valores imutáveis ​​incorporados ao JavaScript. Os números também são imutáveis. Você consegue imaginar um ambiente onde avaliar a expressão 2 + 3 muda o significado do número 2? Parece absurdo, mas fazemos isso com nossos objetos e matrizes o tempo todo.

ahmed khattab
fonte
2

De strings a pilhas ... um exemplo simples de entender tirado do blog de Eric Lippert :

Localização de caminho usando A * em C # 3.0, parte dois ...

Uma pilha mutável como System.Collections.Generic.Stack claramente não é adequada. Queremos ser capazes de pegar um caminho existente e criar novos caminhos a partir dele para todos os vizinhos de seu último elemento, mas colocar um novo nó na pilha padrão modifica a pilha. Teríamos que fazer cópias da pilha antes de empurrá-la, o que é bobagem, porque então estaríamos duplicando todo o seu conteúdo desnecessariamente.

Pilhas imutáveis ​​não têm esse problema. Empurrar para uma pilha imutável apenas cria uma pilha totalmente nova que se conecta à antiga como sua cauda. Como a pilha é imutável, não há perigo de algum outro código aparecer e bagunçar o conteúdo do final. Você pode continuar usando a pilha antiga o quanto quiser.

Para aprofundar no entendimento da imutabilidade, leia as postagens de Eric começando com esta:

Imutabilidade em C # Parte Um: Tipos de Imutabilidade

Leniel Maccaferri
fonte
Essa citação contém uma afirmação estranha - que a estrutura de dados da pilha (na verdade, várias pilhas com compartilhamento de cauda) é, como um todo, uma estrutura mutável - cada push ou pop muda a estrutura. Apenas os itens individuais são imutáveis. E, em princípio, você poderia ter a mesma estrutura, mas com elementos mutáveis. Isso acontece em algumas variações de undoable union-find IIRC. A imutabilidade tem grandes vantagens, mas compartilhar parte ou toda a estrutura de dados como uma otimização é perfeitamente possível com mutáveis. Mesmo se você quiser imutabilidade aparente para outras referências, você sempre pode copiar na gravação conforme necessário.
Steve314
0

Uma maneira de entender esse conceito é observar como o javascript trata todos os objetos, que é por referência. O que significa que todos os objetos são mutáveis após serem instanciados, isso significa que você pode adicionar um objeto com novos métodos e propriedades. Isso é importante porque se você deseja que um objeto seja imutável, ele não pode ser alterado após ser instanciado.

Rick
fonte