Una cadena es inmutable, entonces, ¿por qué no son todas constantes?

8

El stringtipo es inmutable.

Podemos usar la constpalabra clave stringsen un lenguaje de alto nivel como .NET. Mi comprensión de 'const' significa constante (sigue siendo la misma, no podemos cambiar el valor).

¿ stringsNo son siempre constant(OMI, el término constantno debería ser aplicable en el mismo contexto si el tipo tiene que ser recreado cada vez que significa para los valores de tiempo de vida, era constante)?

En lenguajes de alto nivel, específicamente .NET (aunque también me interesaría Java), ¿esto se debe a la gestión / seguimiento general de la memoria de los objetos o hay alguna otra razón?

Dave
fuente
66
¿Qué lenguaje de programación usas? La respuesta puede depender de detalles específicos de la implementación del lenguaje.
Viliam Búr
Su definición de "constante" es difícil de entender. ¿Te refieres a "una vez creado, siempre existe"? En caso afirmativo, la respuesta debería ser obvia: te quedarías sin memoria.
parsifal
1
Si eso no es lo que quieres decir, entonces estás confundiendo objetos y las variables que los señalan. Una "constante" en Java (y supongo que .Net también) es simplemente una variable que nunca se puede cambiar.
parsifal
1
@DaveRook En Java, el finalmodificador en una variable de cadena evita que la variable se cambie para apuntar a una cadena diferente.
1
¿Qué debe ser exactamente constante , qué no se puede modificar exactamente: los caracteres en un objeto de cadena específico o un objeto en una variable específica? Eso son dos cosas diferentes. En Java, las cadenas son inmutables , lo que significa que cuando crea un objeto de cadena, no puede modificarlo ... pero puede tirarlo y colocar otro objeto en la misma variable. La cadena constante ("cadena final estática" en Java) significa que ni siquiera puede reemplazar el objeto en la variable.
Viliam Búr

Respuestas:

22

Estás confundiendo dos cosas diferentes:

  • Inmutable significa que el contenido de la memoria del objeto no se puede modificar. Cuando modifica un objeto inmutable (por ejemplo, a string), el contenido de la memoria de este objeto no se modifica. En lugar:

    1. Se asigna un nuevo bloque de memoria.
    2. El contenido del objeto que (intentó) modificar se copia en este nuevo bloque, con la parte que desea cambiar se cambia en este nuevo bloque.
    3. El puntero (es decir, la referencia) se asigna a este nuevo bloque.
  • Constante significa que la variable no se puede modificar en tiempo de compilación. Si a stringo a integerel contenido de la variable (o lo que apunta) no se puede cambiar o asignar en tiempo de compilación.

rae1
fuente
Gracias. Estoy lejos de ser literal, pero esto lo responde muy bien.
Dave
1
Si no puede modificar la constante en tiempo de compilación, ¿cuándo la modifica?
parsifal
2
@parsifal Si es un constno puede modificarlo. Puede definirlo como un valor inicial, pero no puede asignarle un valor diferente en ningún otro lugar, por lo tanto, no puede modificarlo.
rae1
@ rae1n: esto no es 100% correcto. Constante significa que una variable no se puede modificar en tiempo de ejecución . Es una propiedad de la variable que contiene una cadena, mientras que la inmutabilidad es una propiedad del objeto mismo.
Doc Brown
@DocBrown ¿Estás diciendo que puedes modificar una constante en tiempo de compilación?
rae1
6

Como dicen los comentarios, estás confundiendo "constante" con "inmutable", cuando realmente significan dos cosas muy diferentes.

Una constante es una variable que no se puede cambiar. Dependiendo del idioma y del compilador, es completamente posible que el código compilado simplemente reemplace cada uso de esa variable con el valor asignado, en cuyo caso ni siquiera se le asignaría un lugar en la memoria. Incluso si el compilador no se optimiza de esa manera, todavía se le asigna un lugar en la memoria en el lanzamiento (ya que constimplica static) y permanece allí hasta la salida.

Un inmutable es un valor en la memoria que no se puede cambiar (hasta que se recupere la memoria). Se le asigna un lugar en la memoria según sea necesario, y puede (en teoría) almacenarse en múltiples variables. Asignar a una variable que apunta a un valor inmutable simplemente crea un nuevo inmutable y altera la variable para que apunte a eso. El valor anterior permanece en la memoria hasta que se recolecta la basura, lo que puede suceder incluso mientras el programa se está ejecutando.

Bobson
fuente
3
+1 para explicar qué es lo que realmente está haciendo la constante: alinear el valor de su variable en todas partes donde se hace referencia; que es un mecanismo importante para entender ya que tiene efectos aún mayores que los que se mencionan aquí.
Jimmy Hoffa
2

Las cuerdas no pueden cambiar. Los punteros a las cadenas pueden cambiar. El siguiente es un código válido:

String text = "Text";
text = text.substring(1);

El objeto original "Texto" todavía está allí, sin cambios e inmutable, excepto que ya nada lo señala. Un mutable Stringle permitiría hacerlo text.substring(1)sin tener que asignarlo nuevamente a la textvariable, y cambiaría el objeto original. Si quieres que la variable text no cambie, entonces es cuando la haces a const. Hay casos de uso válidos para ambos.

Como nota al margen, este es un buen ejemplo de un concepto que es más fácil de entender en C ++, porque los objetos y los punteros a los objetos tienen diferentes tipos.

Karl Bielefeldt
fuente
1

Creo que estás confundiendo variables y objetos.

Una variable es simplemente una referencia a un objeto .

Mientras su programa se está ejecutando, una variable puede referirse a múltiples objetos . Asignar algo a la variable no cambia el objeto. Si no hay variables que hagan referencia a un objeto, se convierte en basura.

A Stringse considera inmutable (en Java, y también esperaría en .Net) porque no hay forma de cambiar el objeto .

Una constante es simplemente una variable que no se permite cambiar durante la vida del programa. Define una constante con el finalmodificador en Java y el constmodificador en .Net.

Sin embargo, si su variable "constante" apunta a un objeto mutable, la "constidad" de la variable no afecta la mutabilidad del objeto (en realidad, no puedo decirlo con certeza en .Net, porque estoy asumiendo que hereda algunas de las reglas arcanas de C ++).

parsifal
fuente
@Downvoter: ¿te gustaría comentar? ¿O debería suponer que usted tampoco conoce la diferencia entre una variable y un objeto?
parsifal
1
No soy el votante, pero ¿considera que no todo el mundo es Java o C #?
Ingo
1
@Igno, claro, excepto que el OP dijo "específicamente .NET (aunque estaría interesado en Java", así que limité mis comentarios a esos dos. Dicho eso, la separación entre la variable y el objeto también se aplica a JavaScript, Ruby, Python , Perl y PHP. De hecho, aparte de C ++, no puedo pensar en otro lenguaje moderno que afirme estar orientado a objetos que no haga esta distinción.
parsifal
-1

Una simple demostración de lo que se constlogra. Esto es aplicable a C # y lenguajes similares.

string noconst = "foo";
noconst = "bar"; //noconst has changed! It was declared as "foo" but now is "bar"

const string yesconst = "foo";
yesconst = "bar"; //compiler error
Brian
fuente
1
Si bien esto demuestra cómo se constcomporta, el comportamiento no es exclusivo de const. En Java, la finalpalabra clave se comporta de manera similar y en C # la readonlypalabra clave hace lo mismo. Lo único de a constes que se conoce en tiempo de compilación.
Corbin marzo