Articulo de referencia

objeto inmutable

En la programación orientada a objetos (OO) y la programación funcional , un objeto inmutable ( objeto inalterable [ 1 ] ) es un objeto cuyo estado no puede modificarse después ...

En la programación orientada a objetos (OO) y la programación funcional , un objeto inmutable ( objeto inalterable [ 1 ] ) es un objeto cuyo estado no puede modificarse después de su creación. [ 2 ] Esto contrasta con un objeto mutable (objeto modificable), que puede modificarse después de su creación. [ 3 ] En algunos casos, un objeto se considera inmutable incluso si cambian algunos atributos de uso interno, pero el estado del objeto parece inalterable 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 se suelen expresar como objetos inmutables para mejorar la legibilidad y la eficiencia en 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 ] Otras ventajas son que son más fáciles de entender y razonar sobre ellos, y ofrecen mayor seguridad que los objetos mutables. [ 2 ]

Conceptos

Variables inmutables

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

Los campos de solo lectura pueden calcularse durante la ejecución del programa (a diferencia de las constantes, que se conocen de antemano), pero nunca cambian después de su inicialización.

Inmutabilidad débil frente a inmutabilidad 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 modificables ( inmutabilidad débil ). Si todos los campos son inmutables, entonces el objeto es inmutable. Si todo el objeto no puede ser extendido por otra clase, 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 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 por defecto inmutables, y deben marcarse explícitamente con mutablepara serlo.

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 estos lenguajes son Java , C++ , C# , VB.NET y muchos lenguajes de scripting , como Perl , Python y Ruby . En este caso, es importante saber si el estado de un objeto puede variar cuando los objetos se comparten mediante referencias.

Referenciar objetos frente a copiarlos

Si se sabe que un objeto es inmutable, es preferible crear una referencia al mismo en lugar de copiarlo por completo. Esto se hace para ahorrar memoria al evitar la duplicación de datos y las llamadas a constructores y destructores; además, puede aumentar la velocidad de ejecución.

La técnica de copia de referencias es mucho más difícil de usar para objetos mutables, ya que si un usuario modifica la referencia de un objeto mutable, todos los demás usuarios de dicha referencia verán 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 del objeto completo en lugar de la referencia suele ser una solución sencilla pero costosa. El patrón observador es una técnica alternativa para gestionar los cambios en objetos mutables.

Copia en escritura

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). Mediante esta técnica, cuando un usuario solicita al sistema que copie un objeto, este simplemente crea una nueva referencia que sigue apuntando al mismo objeto. En cuanto un usuario intenta modificar el objeto a través de una referencia específica, el sistema crea una copia real, aplica la modificación y establece la referencia para que apunte a la nueva copia. Los demás usuarios no se ven afectados, ya que siguen haciendo referencia al objeto original. Por lo tanto, con COW, todos los usuarios parecen tener una versión mutable de sus objetos, aunque, en caso de que no los modifiquen, 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 de memoria sin dejar de gestionar correctamente cualquier acción que pueda realizar un programa de aplicación.

Prácticas profesionales

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

Seguridad de los hilos

Los objetos inmutables pueden ser útiles en aplicaciones multihilo. Varios hilos pueden operar sobre los datos representados por objetos inmutables sin preocuparse de que otros hilos los modifiquen. Por lo tanto, los objetos inmutables se consideran más seguros para hilos que los objetos mutables.

Violación de la inmutabilidad

La inmutabilidad no implica que el objeto almacenado en la memoria del ordenador sea imposible de modificar. 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 de forma absoluta (por ejemplo, eludiendo el sistema de tipos o violando la corrección de `const` en C o C++ ).

Detalles específicos del idioma

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

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

Patrones similares son la Interfaz Inmutable y el Envoltorio Inmutable .

En los lenguajes de programación puramente funcionales no es posible crear objetos mutables sin extender el lenguaje (por ejemplo, mediante 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 como variable (es decir mutable; normalmente el valor predeterminado implícito) o constant(es decir inmutable) mediante la constantpalabra clave.

type Some_type is new Integer ; -- podría ser cualquier cosa más complicada x : constant 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 .

procedimiento Hacer_hacer ( a : entrada Entero ; b : entrada salida Entero ; c : salida Entero ) es inicio -- a es inmutable b := b + a ; c := a ; fin Hacer_hacer ;

DO#

En C# se puede forzar la inmutabilidad de los campos de una clase con la readonlyinstrucción. [ 7 ] : 239 Al forzar que todos los campos sean inmutables, el tipo se convierte en un tipo inmutable.

clase ImmutableType { public readonly double Value { get ; }public ImmutableType ( double x ) { Value = x ; }public ImmutableType Square () { return new ImmutableType ( Value * Value ); } }

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

registrar Persona ( cadena Nombre , cadena Apellido );

C++

En C++, una implementación correcta de `const`ShoppingCart permitiría al usuario crear instancias de la clase y luego utilizarlas como constinmutables o mutables, según se desee, proporcionando dos versiones diferentes del items()método. (Cabe destacar que en C++ no es necesario —y de hecho es imposible— proporcionar un constructor especializado para constlas instancias).

importar std ;using std :: vector ; using std :: views :: transform ;clase ShoppingCart { privado : vector <Merchandising> items ; público : explícito Cart ( const vector <Merchandising> & items ) : items { items } { }vector < Mercancía >& artículos () { return artículos ; }const vector < Merchandise >& items () const { return items ; }double computeTotalCost () const { return std :: ranges :: accumulate ( items | transform ([]( const Merchandise & m ) -> double { return m . getPrice (); }), 0.0 ); } };

Tenga en cuenta que, cuando existe un miembro de datos que es un puntero o una referencia a otro objeto, entonces es posible modificar el objeto al que apunta o al que se hace referencia únicamente dentro de un método que no sea constante.

C++ también proporciona inmutabilidad abstracta (a diferencia de la inmutabilidad a nivel de bits) mediante la mutablepalabra clave `inmutable`, que permite cambiar una variable miembroconst desde dentro de un método.

importar std ;using std :: optional ; using std :: vector ; using std :: views :: transform ;clase ShoppingCart { privado : vector <Merchandising> items ; mutable opcional <int> totalCost ; público : explícito Cart ( const vector <Merchandising> & items ) : items { items } { }const vector < Merchandise >& items () const { return items ; }int computeTotalCost () const { if ( ! totalCost ) { totalCost = std :: ranges :: accumulate ( items | transform ([]( const Merchandise & m ) -> double { return m . getPrice (); }), 0.0 ); } return * totalCost ; } };

D

En D , existen dos calificadores de tipo , consty immutable, para variables que no pueden cambiarse. [ 10 ] A diferencia de los 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 qué se aplican: constes una propiedad de la variable: puede haber legalmente referencias mutables al valor referenciado, es decir, el valor puede cambiar. Por el contrario, immutablees una propiedad del valor referenciado: el valor y cualquier cosa accesible transitivamente 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 constcomo o immutable. Básicamente, para cualquier tipo no calificado T, const(T)es la unión disjunta de T(mutable) y immutable(T).

clase Example { Object mutableField ; // mutable const Object constField ; inmutable Object immutableField ; }

Para un Exampleobjeto mutable, se mutableFieldpuede escribir en él. Para un const(Example)objeto, mutableFieldno se puede modificar, hereda const; immutableFieldsigue siendo inmutable ya que es la garantía más fuerte. Para un immutable(Example), todos los campos son inmutables.

En una función como esta:

void fn ( Example m , const Example c , immutable Example i ) { // dentro de las llaves }

Dentro de las llaves, cpodría referirse al mismo objeto que m, por lo que las mutaciones en también mpodrían cambiar indirectamente . Además, podría referirse al mismo objeto que , pero como el valor entonces es inmutable, no hay cambios. Sin embargo, y no pueden referirse legalmente al mismo objeto.ccimi

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

Valores que se inicializan consto immutabledeben inicializarse mediante asignación directa en el punto de declaración o mediante un constructor .

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

La conversión de valores inmutables a mutables provoca un comportamiento indefinido al modificarse, incluso si el valor original proviene de un origen mutable. La conversión de valores mutables a inmutables puede ser válida cuando no quedan referencias mutables posteriormente. «Una expresión puede convertirse de mutable (...) a inmutable si la expresión es única y todas las expresiones a las que se refiere transitivamente son únicas o inmutables». [ 10 ] Si el compilador no puede demostrar la unicidad, la conversión puede realizarse explícitamente y es responsabilidad del programador asegurarse de que no existan referencias mutables.

El tipo stringes un alias para immutable(char)[], es decir, una porción de memoria tipada de caracteres inmutables. [ 11 ] Crear subcadenas es económico, ya que solo copia y modifica un puntero y un campo de longitud, y 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 búferes 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 inmutable y la longitud se copian y las copias son mutables. Los datos a los que se hace referencia no se han copiado y conservan su calificador, en el ejemplo immutable. Se puede eliminar haciendo una copia más profunda, por ejemplo, usando la dupfunción.

Java

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

String s = "ABC" ; s . toLowerCase (); // ¡Esto no logra nada!

El método toLowerCase()no modifica los datos "ABC" que scontiene. En su lugar, se instancia un nuevo objeto String al que se le asignan 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.toLowerCase ( ) ;

Ahora, la clase 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 haga inmutable; más bien, ninguno de los métodos de la clase String afecta los datos que contiene un objeto String, lo que la hace inmutable.

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

Las variables de tipo primitivo ( int, long, short, etc.) pueden reasignarse después de haber sido definidas. Esto puede evitarse utilizando final.

int i = 42 ; // int es un tipo primitivo i = 43 ; // OKfinal 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. finalSolo impide la reasignación.

final MyObject m = new MyObject (); // m es de tipo referencia m.data = 100 ; // OK. 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, Long, Short, Double, Float, Character, Byte, Boolean) también son todos inmutables. Las clases inmutables se pueden implementar siguiendo algunas pautas sencillas. [ 13 ]

JavaScript

En JavaScript , todos los tipos primitivos (Undefined, Null, Boolean, Number, BigInt, String, Symbol) son inmutables, pero los objetos personalizados generalmente son mutables.

function doSomething ( x ) { /* ¿cambiar x aquí cambia el original? */ }; var str = 'una cadena' ; var obj = { an : 'objeto' }; doSomething ( str ); // las cadenas, los números y los tipos booleanos 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 haberlo hecho.

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

var obj = {}; Object.defineProperty ( obj , 'foo' , { value : ' bar' , writable : false } ) ; obj.foo = 'bar2' ; // se ignora silenciosamente

Sin embargo, el método anterior aún permite agregar nuevas propiedades. Como alternativa, se puede usar Object.freeze para hacer que los objetos existentes sean inmutables.

var obj = { foo : 'bar' }; Object . freeze ( obj ); obj . foo = 'bars' ; // no se puede editar la propiedad, se ignora silenciosamente obj . foo2 = 'bar2' ; // no se puede agregar la 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, sino simplemente que el nombre no se puede asignar a un nuevo valor.

const SIEMPRE_IMMUTABLE = true ;try { ALWAYS_IMMUTABLE = false ; } catch ( err ) { console . log ( "No se puede reasignar una referencia inmutable." ); }const arr = [ 1 , 2 , 3 ]; arr . push ( 4 ); console . log ( arr ); // [1, 2, 3, 4]

El uso de estado inmutable se ha convertido en una tendencia creciente en JavaScript desde la introducción de React , que favorece patrones de gestión de estado tipo Flux como Redux . [ 14 ]

Perl

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

paquete Immutable ; usar Moo ;tiene valor => ( es => 'ro' , # solo lectura por defecto => 'data' , # se puede sobrescribir proporcionando al constructor # un valor: Immutable->new(valor => 'algo más'); );1 ;

La creación de una clase inmutable solía requerir dos pasos: primero, crear métodos de acceso (ya sea de forma automática o manual) que impidieran la modificación de los atributos del objeto, y segundo, impedir la modificación directa de los datos de instancia de las instancias de esa clase (esto generalmente se almacenaba en una referencia hash y podía bloquearse con la función lock_hash de Hash::Util):

paquete Immutable ; use strict ; use warnings ; use base qw(Class::Accessor) ; # crear accesores de solo lectura __PACKAGE__ -> mk_ro_accessors ( qw(value) ); use Hash::Util 'lock_hash' ;sub new { my $class = shift ; return $class if ref ( $class ); die "Los argumentos de new deben ser pares clave => valor\n" unless ( @_ % 2 == 0 ); my %defaults = ( value => 'data' , ); my $obj = { %defaults , @_ , }; bless $obj , $class ; # evita la modificación de los datos del objeto lock_hash %$obj ; } 1 ;

O bien, con un accesor escrito manualmente:

paquete Immutable ; usar strict ; usar warnings ; usar Hash::Util 'lock_hash' ;sub new { my $class = shift ; return $class if ref ( $class ); die "Los argumentos de new deben ser pares clave => valor\n" unless ( @_ % 2 == 0 ); my %defaults = ( value => 'data' , ); my $obj = { %defaults , @_ , }; bless $obj , $class ; # evita la modificación de los datos del objeto lock_hash %$obj ; }# accesor de solo lectura sub valor { mi $self = shift ; si ( mi $new_value = shift ) { # intentando establecer un nuevo valor die "Este objeto no se puede modificar\n" ; } else { return $self -> { valor } } } 1 ;

PHP

En PHP existen propiedades de solo lectura desde la versión 8.1 y clases de solo lectura desde la versión 8.2. [ 15 ] [ 16 ]

clase de solo lectura BlogData { public string $title ;Estado público $estado ;public function __construct ( string $title , Status $status ) { $this -> title = $title ; $this -> status = $status ; } }

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 sobrescribir la asignación y eliminación de atributos para generar excepciones:

from typing import Any , NoReturnclase ImmutablePoint : """Una clase inmutable con dos atributos 'x' e 'y'."""__ranuras__ : lista [ str ] = [ "x" , "y" ]def __setattr__ ( self , * args : tuple [ Any , ... ]) -> NoReturn : raise TypeError ( "No se puede modificar una instancia inmutable." )__delattr__ : Invocable [[ Tupla [ Cualquier , ... ]], Sin retorno ] = __setattr__def __init__ ( self , x : int , y : int ) -> None : # Ya no podemos usar self.value = value para almacenar los datos de la instancia # así que debemos llamar explícitamente a la superclase super () . __setattr__ ( "x" , x ) super () . __setattr__ ( "y" , y )

Las funciones auxiliares de la biblioteca estándar collections.namedtuple, typing.NamedTupledisponibles a partir de Python 3.6, crean clases inmutables simples. El siguiente ejemplo es prácticamente equivalente al anterior, además de algunas características similares a las de las tuplas:

from typing import NamedTuple import collectionsPunto : NamedTuple = colecciones.namedtuple ( "Punto" , [ " x " , "y" ])# Lo siguiente crea una tupla con nombre similar a la clase Point ( NamedTuple ) anterior: x : int y : int

Introducido en Python 3.7, dataclassespermite a los desarrolladores emular la inmutabilidad con instancias congeladas . Si se crea una clase de datos congelada, dataclassesse sobrescribirá __setattr__()y __delattr__()se generará un error FrozenInstanceErrorsi se invoca.

from dataclasses import dataclass@dataclass ( frozen = True ) class Point : x : int y : int

Raqueta

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

( struct foo1 ( x y )) ; todos los campos 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. Por defecto, todas las variables y referencias son inmutables. Las variables y referencias mutables se crean explícitamente con la mutpalabra clave `mutable`.

Los elementos constantes en Rust siempre son inmutables.

// Los elementos constantes siempre son inmutables const ALWAYS_IMMUTABLE : bool = true ;struct MyPair { x : usize , y : usize , }fn main () { // Declarar explícitamente una variable mutable let mut mutable_obj = MyPair { x : 1 , y : 2 }; mutable_obj . x = 3 ; // correctolet mutable_ref = & mut mutable_obj ; mutable_ref.x = 1 ; // correctolet immutable_ref = & mutable_obj ; immutable_ref . x = 3 ; // error E0594// Por defecto, las variables son inmutables. let immutable_obj = MyPair { x : 4 , y : 5 }; immutable_obj . x = 6 ; // error E0596let mutable_ref2 = & mut immutable_obj ; // error E0596let immutable_ref2 = & immutable_obj ; immutable_ref2 . x = 6 ; // error E0594 }

Scala

En Scala , cualquier entidad (o, más concretamente, un enlace) puede definirse como mutable o inmutable: en la declaración, se puede usar ` val(value)` para entidades inmutables y ` var(variable)` para entidades mutables. Cabe destacar que, aunque un enlace inmutable no se puede reasignar, puede hacer referencia a un objeto mutable y aún es posible llamar a métodos que modifican dicho 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 entero se infiere en tiempo de compilación) y una entidad mutable llamada currentValue.

Por defecto, 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 modificar una existente. Si bien esto puede parecer ineficiente, la implementación de estas clases y sus garantías de inmutabilidad implican que la nueva instancia puede reutilizar nodos existentes, lo cual, especialmente en el caso de crear copias, es muy eficiente. [ 17 ]

Véase también

Referencias

Este artículo contiene material del libro "Perl Design Patterns Book" (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. 1 2 3 Goetz et al. Java Concurrency in Practice . 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 sobrescribir" . Java Ranch . Consultado el 14 de mayo de 2012. La forma preferida es hacer que la clase sea final. Esto a veces se denomina "inmutabilidad fuerte". Impide que alguien extienda su clase y la haga mutable accidental o deliberadamente.
  5. 1 2 Bloch, Joshua (2018). "Effective Java: Programming Language Guide" (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 registro - Tutorial de C# - C#" . learn.microsoft.com . 14 de noviembre de 2023. Consultado el 23 de febrero de 2024 .
  9. "Registros - Referencia de C# - C#" . learn.microsoft.com . 25 de mayo de 2023. Consultado el 23 de febrero de 2024 .
  10. 1 2 D Especificación del lenguaje §  18
  11. Especificación del lenguaje D §  12.16 (Los términos array y slice se utilizan indistintamente).
  12. "Cómo crear clases y objetos inmutables en Java: ejemplo tutorial" . Javarevisited.blogspot.co.uk. 4 de marzo de 2013. 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" . Desalasworks .
  15. https://www.php.net/releases/8.1/en.php#readonly_properties
  16. https://www.php.net/releases/8.2/en.php#readonly_classes
  17. "API de colecciones de Scala 2.8: clases de colecciones inmutables concretas" . Scala-lang.org . Consultado el 14 de abril de 2014 .
  • Crear objetos inmutables en C# siguiendo 3 sencillos pasos.
  • Artículo Teoría y práctica de Java: ¿Mutar o no mutar? por Brian Goetz , de IBM DeveloperWorks – copia guardada en Internet Archive por Brian Goetz , de IBM DeveloperWorks – copia guardada en Internet Archive
  • Objetos inmutables de JavaPractices.com
  • Objetos inmutables del repositorio de patrones de Portland
  • Immutable.js de Facebook
  • Estructuras inmutables en C# Archivado el 21/12/2017 en el proyecto de código abierto Wayback Machine en Codeplex.
  • Colecciones inmutables en la biblioteca oficial de .NET de Microsoft
  • Objetos inmutables en C# por Tutlane.com
Obtenido de " https://en.wikipedia.org/w/index.php?title=Immutable_object&oldid=1333190200 "