Eu sou novo na programação orientada a objetos, e um conceito que me levou um tempo para entender é a imutabilidade. Acho que a lâmpada se apagou ontem à noite, mas quero verificar:
Quando me deparo com afirmações de que um objeto imutável não pode ser alterado, fico perplexo porque posso, por exemplo, fazer o seguinte:
NSString *myName = @"Bob";
myName = @"Mike";
Lá, eu mudei myName, do tipo imutável NSString. Meu problema é que a palavra "objeto" pode se referir ao objeto físico na memória ou à abstração "meu nome". A definição anterior se aplica ao conceito de imutabilidade.
Quanto à variável, uma definição mais clara (para mim) de imutabilidade é que o valor de um objeto imutável só pode ser alterado mudando também sua localização na memória, ou seja, sua referência (também conhecida como ponteiro).
Isso está correto ou ainda estou perdido na floresta?
fonte
NSString
, é um " ponteiro para eNSString
", o que não é imutável. Eu não sei nada de C objetivo, mas eu estou supondo que no seu exemplo que@"Mike"
é a criação de uma nova instânciaNSString
e atribuindo-o para o ponteiro ,myName
. Portanto, você não alterou o objeto quemyName
estava apontando, apenas para o que estava apontando.Respostas:
Parece que você está indo na direção certa, mas ainda não a conseguiu. Isto está errado:
No seu snippet de código,
myName
não é do tipo imutávelNSString
, é do tipo mutávelNSString*
(ponteiro para NSString). Parece que a principal coisa que você está perdendo é entender que um ponteiro é apenas outro valor e tem uma vida completamente separada da que ele aponta (ou coisas, se você o alterar parcialmente durante sua vida útil).Você diz:
Isto está errado. Um objeto não possui os ponteiros que apontam para ele, nem a localização da memória de um objeto é controlada ou afetada por outros ponteiros.
Portanto, os dois
NSString
objetos no seu exemplo (@"Bob"
e@"Mike"
) são completamente separados damyName
variável. Eles também são completamente separados um do outro. Quando você mudamyName
para apontar para em@"Mike"
vez de apontar para@"Bob"
, você não está alterando osNSString
objetos.Para completar, observarei que os coletores de lixo tornam isso mais complexo, pois as alterações nos ponteiros podem afetar os objetos para os quais eles apontam (ed). No entanto, este é um detalhe de implementação que não deve afetar o comportamento observável do código.
fonte
Você está perdido em palavras. Imutabilidade significa: Contanto que você não altere a variável, ela sempre "conterá" o mesmo valor, não importa o que você faça com outras variáveis.
Contra-exemplo em C (um pouco simplificado, assumindo uma arquitetura que permite isso):
Agora já não "contém" (ou seja, aponta para) a string "Hello World", mas é "Yello World".
Nas linguagens em que as strings são imutáveis, como Java e (EDIT: safe) C #, você não pode fazer isso. De jeito nenhum. Isso significa que todas as partes do programa podem manter com segurança uma referência à string e confiar que seu conteúdo nunca muda; caso contrário, eles teriam que criar uma cópia apenas para estar do lado seguro.
Mas a variável ainda é mutável. Você pode deixá-lo apontar para outro objeto. Só que o objeto em si não muda nas suas costas.
fonte
unsafe
código.Você está confundindo variáveis com objetos. Variáveis podem ser usadas para armazenar referências a objetos, mas NÃO são objetos. São objetos imutáveis, não variáveis; portanto, você pode alterar a variável de um objeto para outro, mas não pode alterar os atributos do objeto, se for imutável.
Pense no objeto como um vizinho barulhento e barulhento. Se ele for razoável (mutável), você poderá bater na porta dele e convertê-lo em um estilo de vida em que ele não faça tanto barulho. Mas se ele é imutável, sua única mudança é esperar que mais alguém se mude!
fonte
Uma variável não é um objeto. Uma variável é um nome, que se refere a um objeto (ou mais geralmente a um valor).
Por exemplo, "o goleiro" é um nome que usamos para nos referir ao objeto (pessoa) responsável pela defesa do gol. Mas se eu substituir essa pessoa por outra (porque a primeira está machucada ou não), a nova pessoa agora é chamada de "goleiro".
A declaração de atribuição é o que torna variáveis mutáveis (alguns idiomas, como Haskell, não o possuem e, de fato, usam variáveis imutáveis). Permite redefinir o significado de um nome e, assim, reatribuir o valor.
Agora, os próprios objetos podem ser imutáveis. Alguns milhares de anos atrás, poderia-se pensar nos diamantes como imutáveis. Não importa o que você fez com um diamante, você não pode modificá-lo. Quer você chamasse waggawooga (traduz-se vagamente na "maior pedra brilhante da nossa tribo") ou deixou de chamá-lo dessa maneira (porque você encontrou uma maior), o diamante permaneceu o mesmo. Por outro lado, o pedaço de madeira que você costumava esculpir em fotos engraçadas com a sua waggawooga não permaneceu o mesmo. Isso se mostrou mutável. Mesmo que tivesse o mesmo nome o tempo todo.
Tanto as variáveis quanto os valores podem ser imutáveis (independentemente). Nesse caso, são os objetos imutáveis. Depois de construir um
NSString
, você não pode modificá-lo. Você pode chamá-lo de nomes e passá-lo, mas permanecerá o mesmo. Em contraste com isso,NSMutableString
pode ser alterado após a criação, por exemplo, chamando osetString
métodofonte
Eu acho que você se sente perdido, porque está misturando dois conceitos: objeto em si e nome da variável vinculado a esse objeto.
Objetos imutáveis não podem ser alterados. Período. No entanto, o nome da variável (símbolo) vinculado a um objeto imutável pode ser modificado para ser vinculado a outro objeto imutável.
Em outras palavras, o que você fez nessas duas linhas foi:
myName
a esse objetomyName
a esse objetofonte
Seu tipo não é um
NSString
, é um " ponteiro para umNSString
", o que não é imutável. Não sei nada sobre o objetivo C, mas, no seu exemplo, acho que@"Mike"
é criar uma nova instânciaNSString
e atribuí-la ao ponteiromyName
. Portanto, você não alterou o objeto quemyName
estava apontando , apenas para o que estava apontando.fonte
Aqui está um exemplo de um objeto mutável: uma matriz
char
em C:Posso alterar o conteúdo do conteúdo
str
para o meu coração (desde que não tenha mais que 10 caracteres). Para que seja reconhecido como uma string pelas funções da biblioteca de strings C, deve haver um 0 à direita, para que ele possa conter strings com até 9 caracteres de comprimento:und weiter .
Compare isso com um objeto de string em Java:
A instância da string (o pedaço de memória que contém os caracteres 'H', 'e', 'l', 'l' e 'o') não pode ser modificado; Não posso alterar nenhum conteúdo dessa sequência. Quando você escreve algo como
você não está anexando "Mundo" ao final da instância "Olá"; você está criando uma nova instância , copiando "Hello World" para ela e atualizando
foo
para se referir a essa nova instância de string.foo
ele próprio não contém a instância da string; refere-se apenas a essa instância (semelhante a um ponteiro em C ou Obj-C); portanto, por que tipos como String são chamados de tipos de referência.fonte