¿Qué significa inmutable?

103

Si una cadena es inmutable, ¿eso significa que .... (supongamos JavaScript)

var str = 'foo';

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

alert(str); // foo

¿Significa que, al llamar a métodos en una cadena, devolverá la cadena modificada, pero no cambiará la cadena inicial?

Si la cadena fuera mutable, ¿eso significa que la segunda alert()también volvería oo?

alex
fuente

Respuestas:

104

Significa que una vez que crea una instancia del objeto, no puede cambiar sus propiedades. En tu primera alerta no estás cambiando de foo. Estás creando una nueva cadena. Es por eso que en su segunda alerta mostrará "foo" en lugar de oo.

¿Significa que, al llamar a métodos en una cadena, devolverá la cadena modificada, pero no cambiará la cadena inicial?

Si. Nada puede cambiar la cadena una vez creada. Ahora bien, esto no significa que no pueda asignar un nuevo objeto de cadena a la strvariable. Simplemente no puede cambiar el objeto actual al que hace referencia str.

Si la cadena fuera mutable, ¿eso significa que la segunda alerta () también devolvería oo?

Técnicamente, no, porque el método de subcadena devuelve una nueva cadena. Hacer que un objeto sea mutable, no cambiaría el método. Hacerlo mutable significa que, técnicamente, podría hacerlo de modo que la subcadena cambie la cadena original en lugar de crear una nueva.

kemiller2002
fuente
La misma cadena si se modifica y se asigna, actualizará la cadena var str = 'foo'; str = str.substr (1)); // oo alerta (str); // oo
Ashwin G
¿Qué pasa con el siguiente código? El valor de la cadena se cambia ahora. var name = "Santosh"; console.log (nombre.substr (0,2)); var name = "kumar" console.log (nombre); Cómo es todavía inmutable
Santosh
97

En un nivel inferior, la inmutabilidad significa que la memoria en la que se almacena la cadena no se modificará. Una vez que crea una cadena "foo", se asigna algo de memoria para almacenar el valor "foo". Esta memoria no se verá alterada. Si modifica la cadena con, digamos substr(1),, se crea una nueva cadena y se asigna una parte diferente de la memoria que se almacenará "oo". Ahora tiene dos cadenas en la memoria "foo"y "oo". Incluso si no va a usar "foo"más, se quedará hasta que se recoja la basura.

Una de las razones por las que las operaciones con cadenas son comparativamente caras.

deceze
fuente
1
Los números también son inmutables.
RN Kushwaha
3
hola desde 2015 !! "En un nivel inferior, la inmutabilidad significa que la memoria en la que está almacenada la cadena no se modificará". --- esto es demasiado restrictivo y no suena bien. La inmutabilidad se trata solo de la tierra del usuario, la memoria virtual puede cambiarse como desee el asignador de memoria tan pronto como se mantengan las invariantes de especificación del lenguaje.
zerkms
2
Esta respuesta es más lógica que la respuesta acertada.
Ejaz Karim
Pero puedo hacer como var str = 'foo'; Puedo modificar a través de str = 'bar'. El valor de str se modificó de esta manera, ¿verdad?
Hacker
@Hacker Nop. Ha asignado una nueva cadena a la variable que apunta a una nueva ubicación en la memoria.
diciembre
13

Inmutable significa aquello que no se puede cambiar ni modificar.

Entonces, cuando asigna un valor a una cadena, este valor se crea desde cero en lugar de ser reemplazado. Entonces, cada vez que se asigna un nuevo valor a la misma cadena, se crea una copia. Entonces, en realidad, nunca cambiará el valor original.

SoftwareGeek
fuente
9

No estoy seguro acerca de JavaScript, pero en Java, las cadenas dan un paso adicional hacia la inmutabilidad, con el "String Constant Pool". Las cadenas se pueden construir con cadenas literales ( "foo") o con un Stringconstructor de clases. Las cadenas construidas con literales de cadena son parte del Grupo de constantes de cadena, y el mismo literal de cadena siempre será la misma dirección de memoria del grupo.

Ejemplo:

    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

En lo anterior, ambos lit1y lit2se construyen usando el mismo literal de cadena, por lo que apuntan a la misma dirección de memoria; lit1 == lit2da como resultado true, porque son exactamente el mismo objeto.

Sin embargo, consse construye utilizando el constructor de clases. Aunque el parámetro es la misma constante de cadena, el constructor asigna nueva memoria para cons, lo que significa consque no es el mismo objeto que lit1y lit2, a pesar de contener los mismos datos.

Por supuesto, dado que las tres cadenas contienen los mismos datos de caracteres, el uso del equalsmétodo devolverá verdadero.

(Ambos tipos de construcción de cuerdas son inmutables, por supuesto)

Brian S
fuente
3

Inmutable significa que el valor no se puede cambiar. Una vez creado, un objeto de cadena no se puede modificar porque es inmutable. Si solicita una subcadena de una cadena, se crea una nueva cadena con la parte solicitada.

El uso de StringBuffer mientras se manipula Strings hace que la operación sea más eficiente, ya que StringBuffer almacena la cadena en una matriz de caracteres con variables para contener la capacidad de la matriz de caracteres y la longitud de la matriz (String en una forma de matriz de caracteres)

Nataraj
fuente
3

La definición del libro de texto de mutabilidad es susceptible o sujeta a cambios o alteraciones. En programación, usamos la palabra para referirnos a objetos cuyo estado puede cambiar con el tiempo. Un valor inmutable es exactamente lo contrario: una vez creado, nunca puede cambiar.

Si esto te parece extraño, permíteme recordarte que muchos de los valores que usamos todo el tiempo son de hecho inmutables.

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

Creo que nadie se sorprenderá al saber que la segunda línea no cambia de ninguna manera la cadena en la declaración. De hecho, ningún método de cadena cambia la cadena en la que operan, todos devuelven cadenas nuevas. La razón es que las cadenas son inmutables: no pueden cambiar, solo podemos crear nuevas cadenas.

Las cadenas no son los únicos valores inmutables integrados en JavaScript. Los números también son inmutables. ¿Puedes siquiera imaginar un entorno en el que evaluar la expresión 2 + 3 cambie el significado del número 2? Suena absurdo, pero hacemos esto con nuestros objetos y matrices todo el tiempo.

ahmed khattab
fuente
2

De cadenas a pilas ... un ejemplo sencillo de entender tomado del blog de Eric Lippert :

Búsqueda de ruta con A * en C # 3.0, segunda parte ...

Una pila mutable como System.Collections.Generic.Stack claramente no es adecuada. Queremos poder tomar una ruta existente y crear nuevas rutas a partir de ella para todos los vecinos de su último elemento, pero empujar un nuevo nodo a la pila estándar modifica la pila. Tendríamos que hacer copias de la pila antes de empujarla, lo cual es una tontería porque entonces estaríamos duplicando todo su contenido innecesariamente.

Las pilas inmutables no tienen este problema. Empujar sobre una pila inmutable simplemente crea una pila nueva que se une a la anterior como su cola. Dado que la pila es inmutable, no hay peligro de que aparezca otro código y se meta con el contenido de la cola. Puede seguir usando la pila anterior al contenido de su corazón.

Para profundizar en la comprensión de la inmutabilidad, lea las publicaciones de Eric que comienzan con esta:

Inmutabilidad en C # Parte uno: tipos de inmutabilidad

Leniel Maccaferri
fuente
Esa cita contiene una afirmación extraña: que la estructura de datos de la pila (en realidad, múltiples pilas con compartición de cola) es, en su conjunto, una estructura mutable: cada empuje o estallido cambia la estructura. Solo los elementos individuales son inmutables. Y en principio, podrías tener la misma estructura pero con elementos mutables. Esto sucede en algunas variaciones del IIRC de búsqueda de unión irrecuperable. La inmutabilidad tiene grandes ventajas, pero compartir parte o la totalidad de una estructura de datos como optimización es perfectamente posible con mutables. Incluso si desea una aparente inmutabilidad para otras referencias, siempre puede copiar sobre escritura según sea necesario.
Steve 314
0

Una forma de comprender este concepto es observar cómo javascript trata todos los objetos, que es por referencia. Lo que significa que todos los objetos son mutables después de ser instanciados, esto significa que puede agregar un objeto con nuevos métodos y propiedades. Esto es importante porque si desea que un objeto sea inmutable, el objeto no puede cambiar después de ser instanciado.

Almiar
fuente