stringtranslate.com

Objeto inmutable

En programación funcional y orientada a objetos (OO), un objeto inmutable (objeto [1] inmutable ) es un objeto cuyo estado no se puede modificar después de su creación. [2] Esto contrasta con un objeto mutable (objeto cambiable), que puede modificarse después de su creación. [3] En algunos casos, un objeto se considera inmutable incluso si algunos atributos utilizados internamente cambian, pero el estado del objeto parece no cambiar desde un punto de vista externo. Por ejemplo, un objeto que utiliza la memorización para almacenar en caché los resultados de cálculos costosos aún podría considerarse un objeto inmutable.

Las cadenas y otros objetos concretos normalmente se expresan como objetos inmutables para mejorar la legibilidad y la eficiencia del tiempo de ejecución en la programación orientada a objetos. Los objetos inmutables también son útiles porque son inherentemente seguros para subprocesos . [2] Otros beneficios son que son más sencillos de entender y razonar y ofrecen mayor seguridad que los objetos mutables. [2]

Conceptos

variables inmutables

En programación imperativa , los valores contenidos en las variables del programa cuyo contenido nunca cambia se conocen como constantes para diferenciarlos de las variables que podrían modificarse durante la ejecución. Los ejemplos incluyen factores de conversión de metros a pies o el valor de pi con varios decimales.

Los campos de sólo lectura se pueden calcular cuando se ejecuta el programa (a diferencia de las constantes, que se conocen de antemano), pero nunca cambian después de que se inicializan.

Inmutabilidad débil versus fuerte

A veces se habla de que ciertos campos de un objeto son inmutables. Esto significa que no hay forma de cambiar esas partes del estado del objeto, aunque otras partes del objeto puedan ser cambiables ( débilmente inmutables ). Si todos los campos son inmutables, entonces el objeto es inmutable. Si otra clase no puede extender el objeto completo, el objeto se denomina fuertemente inmutable . [4] Esto podría, por ejemplo, ayudar a imponer explícitamente ciertas invariantes sobre ciertos datos en el objeto que permanecen iguales durante toda la vida útil del objeto. En algunos lenguajes, esto se hace con una palabra clave (por ejemplo, consten C++ , finalen Java ) que designa el campo como inmutable. Algunos lenguajes lo invierten: en OCaml , los campos de un objeto o registro son inmutables por defecto y deben marcarse explícitamente con mutablepara que así sea.

Referencias a objetos

En la mayoría de los lenguajes orientados a objetos , se puede hacer referencia a los objetos mediante referencias . Algunos ejemplos de dichos lenguajes son Java , C++ , C# , VB.NET y muchos lenguajes de secuencias de comandos , como Perl , Python y Ruby . En este caso, importa si el estado de un objeto puede variar cuando los objetos se comparten mediante referencias.

Hacer referencia o copiar objetos

Si se sabe que un objeto es inmutable, es preferible crear una referencia del mismo en lugar de copiar el objeto completo. Esto se hace para conservar memoria evitando la duplicación de datos y evitando llamadas a constructores y destructores; también da como resultado un aumento potencial en la velocidad de ejecución.

La técnica de copia de referencias es mucho más difícil de usar para objetos mutables, porque si algún usuario de una referencia de objeto mutable la cambia, todos los demás usuarios de esa referencia ven el cambio. Si este no es el efecto deseado, puede resultar difícil notificar a los demás usuarios para que respondan correctamente. En estas situaciones, la copia defensiva de todo el objeto en lugar de la referencia suele ser una solución fácil pero costosa. El patrón de observador es una técnica alternativa para manejar cambios en objetos mutables.

Copiar en escrito

Una técnica que combina las ventajas de los objetos mutables e inmutables y que es compatible directamente con casi todo el hardware moderno es la copia en escritura (COW). Usando esta técnica, cuando un usuario le pide al sistema que copie un objeto, simplemente crea una nueva referencia que todavía apunta al mismo objeto. Tan pronto como un usuario intenta modificar el objeto a través de una referencia particular, el sistema hace una copia real, le aplica la modificación y establece la referencia para que haga referencia a la nueva copia. Los demás usuarios no se ven afectados porque todavía hacen referencia al objeto original. Por lo tanto, bajo COW, todos los usuarios parecen tener una versión mutable de sus objetos, aunque en el caso de que los usuarios no modifiquen sus objetos, se conservan las ventajas de ahorro de espacio y velocidad de los objetos inmutables. La copia en escritura es popular en los sistemas de memoria virtual porque les permite ahorrar espacio en la memoria y al mismo tiempo manejar correctamente cualquier cosa que pueda hacer un programa de aplicación.

pasantía

La práctica de utilizar siempre referencias en lugar de copias de objetos iguales se conoce como internamiento . Si se utiliza internación, dos objetos se consideran iguales si y sólo si sus referencias, normalmente representadas como punteros o números enteros, son iguales. Algunos lenguajes hacen esto automáticamente: por ejemplo, Python interna automáticamente cadenas cortas . Si se garantiza que el algoritmo que implementa el internado lo hará en todos los casos posibles, entonces comparar la igualdad de los objetos se reduce a comparar sus punteros: una ganancia sustancial en velocidad en la mayoría de las aplicaciones. (Incluso si no se garantiza que el algoritmo sea completo, todavía existe la posibilidad de una mejora rápida en el caso cuando los objetos son iguales y usan la misma referencia). La pasantía generalmente solo es útil para objetos inmutables.

Seguridad del hilo

Los objetos inmutables pueden resultar útiles en aplicaciones multiproceso. Varios subprocesos pueden actuar sobre datos representados por objetos inmutables sin preocuparse de que otros subprocesos cambien los datos. Por lo tanto, los objetos inmutables se consideran más seguros para subprocesos que los objetos mutables.

Violando la inmutabilidad

La inmutabilidad no implica que el objeto almacenado en la memoria de la computadora no se pueda escribir. Más bien, la inmutabilidad es una construcción en tiempo de compilación que indica lo que un programador puede hacer a través de la interfaz normal del objeto, no necesariamente lo que puede hacer en absoluto (por ejemplo, eludiendo el sistema de tipos o violando la corrección constante en C o C++ ).

Detalles específicos del idioma

En Python , Java [5] : 80  y .NET Framework , las cadenas son objetos inmutables. Tanto Java como .NET Framework tienen versiones mutables de cadenas. En Java [5] : 84  estos son StringBuffery StringBuilder(versiones mutables de Java String) y en .NET esto es StringBuilder(versión mutable de .Net String). Python 3 tiene una variante de cadena mutable (bytes), denominada bytearray. [6]

Además, todas las clases contenedoras primitivas en Java son inmutables.

Patrones similares son Immutable Interface e Immutable Wrapper.

En lenguajes de programación puramente funcionales no es posible crear objetos mutables sin extender el lenguaje (por ejemplo, a través de una biblioteca de referencias mutables o una interfaz de función externa ), por lo que todos los objetos son inmutables.

ada

En Ada , cualquier objeto se declara variable (es decir, mutable; normalmente el valor predeterminado implícito) o constant(es decir, inmutable) mediante la constantpalabra clave.

 escriba  Some_type  es  un nuevo  entero ;  -- podría ser algo más complicado  x :  constante  Some_type :=  1 ;  - inmutable  y :  Some_type ;  -- mutable

Los parámetros del subprograma son inmutables en el modo de entrada y mutables en los modos de entrada y salida .

 el procedimiento  Do_it ( a : in  Integer ;  b : in  out  Integer ;  c : out  Integer )  es  comenzar  - a es inmutable  b :=  b  +  a ;  c :=  a ;  finalizar  Hazlo ;

C#

En C# puedes imponer la inmutabilidad de los campos de una clase con la readonlydeclaración. [7] : 239  Al hacer cumplir que todos los campos sean inmutables, se obtiene un tipo inmutable.

clase AnImmutableType { público solo lectura doble _valor ; público AnImmutableType ( doble x ) { _valor = x ; } public AnImmutableType Square () { return nuevo AnImmutableType ( _valor * _valor ); } }                             

C# tiene registros que son inmutables. [8] [9]

registrar Persona ( cadena Nombre , cadena Apellido );    

C++

En C++, una implementación constante y correctaCart de permitiría al usuario crear instancias de la clase y luego usarlas como const(inmutables) o mutables, según lo desee, proporcionando dos versiones diferentes del items()método. (Observe que en C++ no es necesario (y de hecho imposible) proporcionar un constructor especializado para constlas instancias).

clase Carrito { público : Carrito ( std :: vector < Artículo > artículos ) : artículos_ ( artículos ) {}        std :: vector < Artículo >& artículos () { devolver artículos_ ; } const std :: vector < Artículo >& elementos () const { devolver elementos_ ; }              int ComputeTotalCost () const { /* devuelve la suma de los precios */ }      privado : std :: vector < Artículo > artículos_ ; };  

Tenga en cuenta que, cuando hay un miembro de datos que es un puntero o referencia a otro objeto, entonces es posible mutar el objeto al que se apunta o al que se hace referencia solo dentro de un método no constante.

C++ también proporciona inmutabilidad abstracta (a diferencia de bit a bit) a través de la mutablepalabra clave, que permite cambiar una variable miembroconst desde dentro de un método.

clase Carrito { público : Carrito ( std :: vector < Artículo > artículos ) : artículos_ ( artículos ) {}        const std :: vector < Artículo >& artículos () const { devolver artículos_ ; }        int ComputeTotalCost () const { if ( total_cost_ ) { return * total_cost_ ; }          int costo_total = 0 ; for ( const auto & item : items_ ) { total_cost += item . Costo (); } costo_total_ = costo_total ; devolver costo_total ; }                     privado : std :: vector < Artículo > artículos_ ; std mutable :: opcional <int> total_cost_ ;};     

D

En D , existen dos calificadores de tipo , consty immutable, para variables que no se pueden cambiar. [10] A diferencia de C++ const, Java finaly C# readonly, son transitivos y se aplican recursivamente a cualquier cosa accesible a través de referencias de dicha variable. La diferencia entre consty immutablees a lo que se aplican: constes una propiedad de la variable: pueden existir legalmente referencias mutables al valor referido, es decir, el valor realmente puede cambiar. Por el contrario, immutablees una propiedad del valor referido: el valor y cualquier cosa transitivamente alcanzable desde él no pueden cambiar (sin romper el sistema de tipos, lo que lleva a un comportamiento indefinido ). Cualquier referencia de ese valor debe estar marcada consto immutable. Básicamente, para cualquier tipo no calificado T, const(T)es la unión disjunta de T(mutable) y immutable(T).

clase C { /*mutable*/ Objeto mField ; const Objeto cCampo ; Objeto inmutable iField ; }           

Para un Cobjeto mutable, mFieldse puede escribir en él. Para un const(C)objeto, mFieldno se puede modificar, hereda const; iFieldsigue siendo inmutable ya que es la garantía más fuerte. Para an immutable(C), todos los campos son inmutables.

En una función como esta:

función vacía ( C m , const C c , inmutable C i ) { /* dentro de las llaves */ }          

Dentro de las llaves, cpodría referirse al mismo objeto que m, por lo que las mutaciones también mpodrían cambiar indirectamente . cAdemás, cpodría referirse al mismo objeto que i, pero como el valor es inmutable, no hay cambios. Sin embargo, legalmente mno ipueden referirse al mismo objeto.

En el lenguaje de las garantías, mutable no tiene garantías (la función podría cambiar el objeto), constes una garantía externa de que la función no cambiará nada y immutablees una garantía bidireccional (la función no cambiará el valor y la persona que llama debe no cambiarlo).

Valores que son consto immutabledeben ser inicializados mediante asignación directa en el momento de la declaración o por un constructor .

Debido a que constlos parámetros olvidan si el valor era mutable o no, una construcción similar, inoutactúa, en cierto sentido, como una variable para la información de mutabilidad. Una función de tipo const(S) function(const(T))devuelve const(S)valores escritos para argumentos mutables, constantes e inmutables. Por el contrario, una función de tipo inout(S) function(inout(T))devuelve argumentos Smutables T, const(S)valores const(T)y immutable(S)valores immutable(T).

Convertir valores inmutables en mutables inflige un comportamiento indefinido tras el cambio, incluso si el valor original proviene de un origen mutable. Convertir valores mutables a inmutables puede ser legal cuando no quedan referencias mutables después. "Una expresión puede convertirse de mutable (...) a inmutable si la expresión es única y todas las expresiones a las que hace referencia transitivamente son únicas o inmutables". [10] Si el compilador no puede demostrar la unicidad, la conversión se puede realizar explícitamente y depende del programador asegurarse de que no existan referencias mutables.

El tipo stringes un alias para immutable(char)[], es decir, una porción de memoria escrita de caracteres inmutables. [11] Crear subcadenas es económico, ya que simplemente copia y modifica un puntero y un archivo de longitud, y es seguro, ya que los datos subyacentes no se pueden cambiar. Los objetos de tipo const(char)[]pueden hacer referencia a cadenas, pero también a buffers mutables.

Hacer una copia superficial de un valor constante o inmutable elimina la capa externa de inmutabilidad: copiar una cadena inmutable ( immutable(char[])) devuelve una cadena ( immutable(char)[]). El puntero y la longitud inmutables se están copiando y las copias son mutables. El dato referido no ha sido copiado y mantiene su calificador, en el ejemplo immutable. Se puede eliminar haciendo una copia detallada, por ejemplo usando la dupfunción.

Java

Un ejemplo clásico de un objeto inmutable es una instancia de la Stringclase Java.

Cadena s = "ABC" ; s . a minúsculas (); // ¡Esto no logra nada!    

El método toLowerCase()no cambia los datos "ABC" que scontiene. En su lugar, se crea una instancia de un nuevo objeto String y se le proporcionan los datos "abc" durante su construcción. El método devuelve una referencia a este objeto String toLowerCase(). Para que la cadena scontenga los datos "abc", se necesita un enfoque diferente:

s = s . a minúsculas ();  

Ahora String shace referencia a un nuevo objeto String que contiene "abc". No hay nada en la sintaxis de la declaración de la clase String que la obligue a ser inmutable; más bien, ninguno de los métodos de la clase String afecta los datos que contiene un objeto String, lo que lo hace inmutable.

La palabra clave final( artículo detallado ) se utiliza para implementar tipos primitivos inmutables y referencias de objetos, [12] pero no puede, por sí sola, hacer que los objetos en sí sean inmutables. Vea los ejemplos a continuación:

Las variables de tipo primitivo ( int,,, etc.) se pueden reasignar después de definirlas. Esto se puede prevenir usando .longshortfinal

int yo = 42 ; //int es un tipo primitivo i = 43 ; // DE ACUERDO       final int j = 42 ; j = 43 ; // no compila. j es final por lo que no se puede reasignar       

Los tipos de referencia no se pueden hacer inmutables simplemente usando la finalpalabra clave. finalsólo impide la reasignación.

final MiObjeto m = nuevo MiObjeto (); //m es de tipo de referencia m . datos = 100 ; // DE ACUERDO. Podemos cambiar el estado del objeto m (m es mutable y final no cambia este hecho) m = new MyObject (); // no compila. m es final por lo que no se puede reasignar             

Los envoltorios primitivos ( Integer,,,,,,,,, ) también son todos inmutables. Las clases inmutables se pueden implementar siguiendo algunas pautas simples. [13]LongShortDoubleFloatCharacterByteBoolean

javascript

En JavaScript , todos los tipos primitivos (Indefinido, Nulo, Booleano, Número, BigInt, Cadena, Símbolo) son inmutables, pero los objetos personalizados generalmente son mutables.

function doSomething ( x ) { /* ¿cambiar x aquí cambia el original? */ }; var cadena = 'una cadena' ; var obj = { an : 'objeto' }; hacer algo ( cadena ); // cadenas, números y tipos bool son inmutables, la función obtiene una copia doSomething ( obj ); // los objetos se pasan por referencia y son mutables dentro de la función doAnotherThing ( str , obj ); // `str` no ha cambiado, pero `obj` puede que sí.                 

Para simular la inmutabilidad en un objeto, se pueden definir propiedades como de solo lectura (escribibles: falso).

var objeto = {}; Objeto . defineProperty ( obj , 'foo' , { valor : 'barra' , escribible : falso }); objeto . foo = 'barra2' ; // ignorado silenciosamente             

Sin embargo, el enfoque anterior aún permite agregar nuevas propiedades. Alternativamente, se puede usar Object.freeze para hacer que los objetos existentes sean inmutables.

var obj = { foo : 'barra' }; Objeto . congelar ( obj ); objeto . foo = 'barras' ; // no se puede editar la propiedad, se ignora silenciosamente obj . foo2 = 'barra2' ; // no se puede agregar propiedad, se ignora silenciosamente            

Con la implementación de ECMA262, JavaScript tiene la capacidad de crear referencias inmutables que no se pueden reasignar. Sin embargo, usar una constdeclaración no significa que el valor de la referencia de solo lectura sea inmutable, solo que el nombre no se puede asignar a un nuevo valor.

const ALWAYS_IMMUTABLE = verdadero ;   prueba { ALWAYS_IMMUTABLE = false ; } captura ( err ) { consola . log ( "No se puede reasignar una referencia inmutable." ); }        ajuste constante = [ 1 , 2 , 3 ]; llegar . empujar ( 4 ); consola . iniciar sesión ( arr ); // [1, 2, 3, 4]      

El uso de estados inmutables se ha convertido en una tendencia creciente en JavaScript desde la introducción de React , que favorece los patrones de gestión de estados similares a Flux, como Redux . [14]

perla

En Perl , se puede crear una clase inmutable con la biblioteca Moo simplemente declarando todos los atributos de solo lectura:

paquete Inmutable ; utilizar muuuu ;  tiene valor => ( is => 'ro' , # solo lectura predeterminada => 'data' , # se puede anular proporcionando al constructor # un valor: Immutable->new(value => 'algo más'); ) ;            1 ;

La creación de una clase inmutable solía requerir dos pasos: primero, crear accesores (ya sea automática o manualmente) que impidan la modificación de los atributos del objeto y, en segundo lugar, evitar la modificación directa de los datos de instancia de las instancias de esa clase (esto generalmente se almacenaba en un hash). referencia, y podría bloquearse con la función lock_hash de Hash::Util):

paquete Inmutable ; utilizar estricto ; utilizar advertencias ; utilizar base qw(Clase::Accesor) ; # crear accesores de solo lectura __PACKAGE__ -> mk_ro_accessors ( qw(valor) ); utilizar Hash::Util 'lock_hash' ;       sub nuevo { mi $clase = turno ; devolver $clase si ref ( $clase ); die "Los argumentos para new deben ser pares clave => valor\n" a menos que ( @_ % 2 == 0 ); mis %valores predeterminados = ( valor => 'datos' , ); mi $obj = { %valores predeterminados , @_ , }; bendice $obj , $clase ; # evitar la modificación de los datos del objeto lock_hash %$obj ; } 1 ;                                       

O, con un descriptor de acceso escrito manualmente:

paquete Inmutable ; utilizar estricto ; utilizar advertencias ; utilizar Hash::Util 'lock_hash' ;     sub nuevo { mi $clase = turno ; devolver $clase si ref ( $clase ); die "Los argumentos para new deben ser pares clave => valor\n" a menos que ( @_ % 2 == 0 ); mis %valores predeterminados = ( valor => 'datos' , ); mi $obj = { %valores predeterminados , @_ , }; bendice $obj , $clase ; # evitar la modificación de los datos del objeto lock_hash %$obj ; }                                       # subvalor del descriptor de acceso de solo lectura { my $ self = shift ; if ( my $new_value = shift ) { # intentando establecer un nuevo valor die "Este objeto no se puede modificar\n" ; } else { return $self -> { valor } } } 1 ;                     

Pitón

En Python , algunos tipos integrados (números, booleanos, cadenas, tuplas, conjuntos congelados) son inmutables, pero las clases personalizadas generalmente son mutables. Para simular la inmutabilidad en una clase, se podría anular la configuración y eliminación de atributos para generar excepciones:

class  ImmutablePoint : """Una clase inmutable con dos atributos 'x' e 'y'."""  __ranuras__  =  [ 'x' ,  'y' ] def  __setattr__ ( self ,  * args ):  rise  TypeError ( "No se puede modificar la instancia inmutable" ) . __delattr__  =  __setattr__ def  __init__ ( self ,  x ,  y ):  # Ya no podemos usar self.value = value para almacenar los datos de la instancia  # por lo que debemos llamar explícitamente a la superclase  super () . __setattr __( 'x' ,  x )  super () . __setattr__ ( 'y' ,  y )

Las bibliotecas auxiliares estándar collections.namedtuple y Typing.NamedTuple, disponibles desde Python 3.6 en adelante, crean clases simples e inmutables. El siguiente ejemplo es aproximadamente equivalente al anterior, además de algunas características similares a las de una tupla:

al  escribir  importar  colecciones de importación NamedTuple Punto  =  colecciones . tupla con nombre ( 'Punto' ,  [ 'x' ,  'y' ])# lo siguiente crea una tupla con nombre similar a la clase anterior  Punto ( NamedTuple ):  x :  int  y :  int

Introducidas en Python 3.7, las clases de datos permiten a los desarrolladores emular la inmutabilidad con instancias congeladas. Si se crea una clase de datos congelada, dataclassesse anulará __setattr__()y __delattr__()se generará FrozenInstanceErrorsi se invoca.

desde  clases de datos  importar  clase de datos@dataclass ( congelado = Verdadero ) clase  Punto :  x :  int  y :  int

Raqueta

Racket se diferencia sustancialmente de otras implementaciones de Scheme al hacer que su tipo de par central ("células contras") sea inmutable. En su lugar, proporciona un tipo de par mutable paralelo, a través de mcons, mcar, set-mcar!etc. Además, se admiten muchos tipos inmutables, por ejemplo, cadenas y vectores inmutables, y se utilizan ampliamente. Las nuevas estructuras son inmutables de forma predeterminada, a menos que un campo se declare específicamente mutable o toda la estructura:

( estructura foo1 ( x y )) ; todos los campos son inmutables ( struct foo2 ( x [ y #:mutable ])) ; un campo mutable ( struct foo3 ( x y ) #:mutable ) ; todos los campos mutables              

El lenguaje también admite tablas hash inmutables, implementadas funcionalmente y diccionarios inmutables.

Óxido

El sistema de propiedad de Rust permite a los desarrolladores declarar variables inmutables y pasar referencias inmutables. De forma predeterminada, todas las variables y referencias son inmutables. Las variables mutables y las referencias se crean explícitamente con la mutpalabra clave.

Los elementos constantes en Rust siempre son inmutables.

// los elementos constantes son siempre inmutables const ALWAYS_IMMUTABLE : bool = true ;    Objeto de estructura { x : usar tamaño , y : usar tamaño , }   fn  main () { // declarar explícitamente una variable mutable let mut mutable_obj = Objeto { x : 1 , y : 2 }; objeto_mutable . x = 3 ; // bueno                let mutable_ref = & mut mutable_obj ; referencia_mutable . x = 1 ; // bueno         let immutable_ref = & mutable_obj ; referencia_inmutable . x = 3 ; // error E0594        // por defecto, las variables son inmutables let immutable_obj = Object { x : 4 , y : 5 }; objeto_inmutable . x = 6 ; // error E0596             let mutable_ref2 = & mut immutable_obj ; // error E0596       let immutable_ref2 = & immutable_obj ; inmutable_ref2 . x = 6 ; // error E0594 }        

escala

En Scala , cualquier entidad (en sentido estricto, un enlace) se puede definir como mutable o inmutable: en la declaración, se puede usar val(valor) para entidades inmutables y var(variable) para entidades mutables. Tenga en cuenta que, aunque un enlace inmutable no se puede reasignar, aún puede hacer referencia a un objeto mutable y aún es posible llamar a métodos mutantes en ese objeto: el enlace es inmutable, pero el objeto subyacente puede ser mutable.

Por ejemplo, el siguiente fragmento de código:

val valormax = 100 var valoractual = 1      

define una entidad inmutable maxValue(el tipo de entero se infiere en tiempo de compilación) y una entidad mutable denominada currentValue.

De forma predeterminada, las clases de colección como Listy Mapson inmutables, por lo que los métodos de actualización devuelven una nueva instancia en lugar de mutar una existente. Si bien esto puede parecer ineficiente, la implementación de estas clases y sus garantías de inmutabilidad significan que la nueva instancia puede reutilizar nodos existentes, lo cual, especialmente en el caso de crear copias, es muy eficiente. [15] [ se necesita una mejor fuente ]

Ver también

Referencias

Este artículo contiene material del libro de patrones de diseño de Perl.

  1. ^ "adjetivo inmutable - Definición, imágenes, pronunciación y notas de uso - Oxford Advanced Learner's Dictionary en OxfordLearnersDictionaries.com". www.oxfordlearnersdictionaries.com .
  2. ^ a b C Goetz et al. "Concurrencia de Java en la práctica" . Addison Wesley Professional, 2006, Sección 3.4. Inmutabilidad
  3. ^ "6.005 - Construcción de software".
  4. ^ David O'Meara (abril de 2003). "Objetos mutables e inmutables: asegúrese de que los métodos no se puedan anular". Rancho Java . Consultado el 14 de mayo de 2012 . La forma preferida es hacer que la clase sea definitiva. Esto a veces se denomina "inmutabilidad fuerte". Evita que alguien extienda su clase y la haga mutable accidental o deliberadamente.
  5. ^ ab Bloch, Joshua (2018). "Java efectivo: Guía del lenguaje de programación" (tercera ed.). Addison-Wesley. ISBN 978-0134685991.
  6. ^ "Funciones integradas: documentación de Python v3.0". docs.python.org .
  7. ^ Skeet, Jon (23 de marzo de 2019). C# en profundidad . Manning. ISBN 978-1617294532.
  8. ^ "Usar tipos de registros - Tutorial de C# - C#". aprender.microsoft.com . 14 de noviembre de 2023 . Consultado el 23 de febrero de 2024 .
  9. ^ "Registros - Referencia de C# - C#". aprender.microsoft.com . 25 de mayo de 2023 . Consultado el 23 de febrero de 2024 .
  10. ^ ab D Especificación del lenguaje § 18
  11. ^ Especificación del lenguaje D § 12.16 (Los términos matriz y segmento se usan indistintamente).
  12. ^ "Cómo crear clases y objetos inmutables en Java: ejemplo de tutorial". Javarevisited.blogspot.co.uk. 2013-03-04 . Consultado el 14 de abril de 2014 .
  13. ^ "Objetos inmutables". javapractices.com . Consultado el 15 de noviembre de 2012 .
  14. ^ "Inmutabilidad en JavaScript: una visión contraria". Obras Desalas .
  15. ^ "API de colecciones de Scala 2.8: clases de colecciones concretas e inmutables". Scala-lang.org . Consultado el 14 de abril de 2014 .

enlaces externos