词条 | Immutable object |
释义 |
In object-oriented and functional programming, an immutable object (unchangeable[1] object) is an object whose state cannot be modified after it is created.[2] This is in contrast to a mutable object (changeable object), which can be modified after it is created. In some cases, an object is considered immutable even if some internally used attributes change, but the object's state appears unchanging from an external point of view. For example, an object that uses memoization to cache the results of expensive computations could still be considered an immutable object. Strings and other concrete objects are typically expressed as immutable objects to improve readability and runtime efficiency in object-oriented programming. Immutable objects are also useful because they are inherently thread-safe.[2] Other benefits are that they are simpler to understand and reason about and offer higher security than mutable objects.[2] ConceptsImmutable variablesIn imperative programming, values held in program variables whose content never changes are known as constants to differentiate them from variables that could be altered during execution. Examples include conversion factors from meters to feet, or the value of pi to several decimal places. Read-only fields may be calculated when the program runs (unlike constants, which are known beforehand), but never change after they are initialized. Weak vs strong immutabilitySometimes, one talks of certain fields of an object being immutable. This means that there is no way to change those parts of the object state, even though other parts of the object may be changeable (weakly immutable). If all fields are immutable, then the object is immutable. If the whole object cannot be extended by another class, the object is called strongly immutable.[3] This might, for example, help to explicitly enforce certain invariants about certain data in the object staying the same through the lifetime of the object. In some languages, this is done with a keyword (e.g. References to objectsIn most object-oriented languages, objects can be referred to using references. Some examples of such languages are Java, C++, C#, VB.NET, and many scripting languages, such as Perl, Python, and Ruby. In this case, it matters whether the state of an object can vary when objects are shared via references. Copying objectsIf an object is known to be immutable, it can be copied simply by making a copy of a reference to it instead of copying the entire object. Because a reference (typically only the size of a pointer) is usually much smaller than the object itself, this results in memory savings and a potential boost in execution speed. The reference copying technique is much more difficult to use for mutable objects, because if any user of a mutable object reference changes it, all other users of that reference see the change. If this is not the intended effect, it can be difficult to notify the other users to have them respond correctly. In these situations, defensive copying of the entire object rather than the reference is usually an easy but costly solution. The observer pattern is an alternative technique for handling changes to mutable objects. Copy-on-writeA technique that blends the advantages of mutable and immutable objects, and is supported directly in almost all modern hardware, is copy-on-write (COW). Using this technique, when a user asks the system to copy an object, it instead merely creates a new reference that still points to the same object. As soon as a user attempts to modify the object through a particular reference, the system makes a real copy, applies the modification to that, and sets the reference to refer to the new copy. The other users are unaffected, because they still refer to the original object. Therefore, under COW, all users appear to have a mutable version of their objects, although in the case that users do not modify their objects, the space-saving and speed advantages of immutable objects are preserved. Copy-on-write is popular in virtual memory systems because it allows them to save memory space while still correctly handling anything an application program might do. InterningThe practice of always using references in place of copies of equal objects is known as interning. If interning is used, two objects are considered equal if and only if their references, typically represented as pointers or integers, are equal. Some languages do this automatically: for example, Python automatically interns short strings. If the algorithm that implements interning is guaranteed to do so in every case that it is possible, then comparing objects for equality is reduced to comparing their pointers – a substantial gain in speed in most applications. (Even if the algorithm is not guaranteed to be comprehensive, there still exists the possibility of a fast path case improvement when the objects are equal and use the same reference.) Interning is generally only useful for immutable objects. Thread safetyImmutable objects can be useful in multi-threaded applications. Multiple threads can act on data represented by immutable objects without concern of the data being changed by other threads. Immutable objects are therefore considered more thread-safe than mutable objects. Violating immutabilityImmutability does not imply that the object as stored in the computer's memory is unwriteable. Rather, immutability is a compile-time construct that indicates what a programmer can do through the normal interface of the object, not necessarily what they can absolutely do (for instance, by circumventing the type system or violating const correctness in C or C++). Language-specific detailsIn Python, Java and the .NET Framework, strings are immutable objects. Both Java and the .NET Framework have mutable versions of string. In Java these are Additionally, all of the primitive wrapper classes in Java are immutable. Similar patterns are the Immutable Interface and Immutable Wrapper. In pure functional programming languages it is not possible to create mutable objects without extending the language (e.g. via a mutable references library or a foreign function interface), so all objects are immutable. AdaIn Ada, any object is declared either variable (i.e. mutable; typically the implicit default), or type Some_type is new Integer; -- could be anything more complicated x: constant Some_type:= 1; -- immutable y: Some_type; -- mutable Subprogram parameters are immutable in the in mode, and mutable in the in out and out modes. procedure Do_it(a: in Integer; b: in out Integer; c: out Integer) is begin -- a is immutable b:= b + a; c:= a; end Do_it; C#In C# you can enforce immutability of the fields of a class with the By enforcing all the fields as immutable, you obtain an immutable type. class AnImmutableType {public readonly double _value; public AnImmutableType(double x) { _value = x; } public AnImmutableType Square() { return new AnImmutableType(_value*_value); } } C++In C++, a const-correct implementation of template class Cart { private: std::vector public: Cart(const std::vector std::vector Note that, if there were a field that is a pointer or reference to another object, then it might still be possible to mutate the object pointed to by such a pointer or reference within a const method, without violating const-correctness. It can be argued that in such a case the object is not really immutable. C++ also provides abstract (as opposed to bitwise) immutability via the template class Cart { private: std::vector public: Cart(const std::vector const std::vector totaled = true; } return costInCents; } }; DIn D, there exist two type qualifiers, class C { /*mutable*/ Object mField; const Object cField; immutable Object iField; } For a mutable In a function like this: void func(C m, const C c, immutable C i) { /* inside the braces */ }Inside the braces,
In the language of guarantees, mutable has no guarantees (the function might change the object),
Values that are Because A function of type Casting immutable values to mutable inflicts undefined behavior upon change, even if the original value comes from a mutable origin. Casting mutable values to immutable can be legal when there remain no mutable references afterward. "An expression may be converted from mutable (...) to immutable if the expression is unique and all expressions it transitively refers to are either unique or immutable."[5] If the compiler cannot prove uniqueness, the casting can be done explicitly and it is up to the programmer to ensure that no mutable references exist. The type Making a shallow copy of a const or immutable value removes the outer layer of immutablity: Copying an immutable string ( JavaA classic example of an immutable object is an instance of the Java String s = "ABC"; s.toLowerCase(); The method s = s.toLowerCase(); Now the String The keyword Primitive type variables ( int i = 42; //int is a primitive type i = 43; // OK final int j = 42; j = 43; // does not compile. j is final so can't be reassigned Reference types cannot be made immutable just by using the final MyObject m = new MyObject(); //m is of reference type m.data = 100; // OK. We can change state of object m (m is mutable and final doesn't change this fact) m = new MyObject(); // does not compile. m is final so can't be reassigned Primitive wrappers ( PerlIn Perl, one can create an immutable class with the Moo library by simply declaring all the attributes read only: package Immutable; use Moo; has value => ( is => 'ro', # read only default => 'data', # can be overridden by supplying the constructor with # a value: Immutable->new(value => 'something else'); ); 1; Creating an immutable class used to require two steps: first, creating accessors (either automatically or manually) that prevent modification of object attributes, and secondly, preventing direct modification of the instance data of instances of that class (this was usually stored in a hash reference, and could be locked with Hash::Util's lock_hash function): package Immutable; use strict; use warnings; use base qw(Class::Accessor);
__PACKAGE__->mk_ro_accessors(qw(value)); use Hash::Util 'lock_hash'; sub new { my $class = shift; return $class if ref($class); die "Arguments to new must be key => value pairs\" unless (@_ % 2 == 0); my %defaults = ( value => 'data', ); my $obj = { %defaults, @_, }; bless $obj, $class; # prevent modification of the object data lock_hash %$obj; } 1; Or, with a manually written accessor: package Immutable; use strict; use warnings; use Hash::Util 'lock_hash'; sub new { my $class = shift; return $class if ref($class); die "Arguments to new must be key => value pairs\" unless (@_ % 2 == 0); my %defaults = ( value => 'data', ); my $obj = { %defaults, @_, }; bless $obj, $class; # prevent modification of the object data lock_hash %$obj; }
sub value { my $self = shift; if (my $new_value = shift) { # trying to set a new value die "This object cannot be modified\"; } else { return $self->{value} } } 1; PythonIn Python, some built-in types (numbers, booleans, strings, tuples, frozensets) are immutable, but custom classes are generally mutable. To simulate immutability in a class, one should override attribute setting and deletion to raise exceptions: class ImmutablePoint(object): def __setattr__(self, *args): raise TypeError("Can not modify immutable instance") def __init__(self, x, y): # We can no longer use self.value = value to store the instance data # so we must explicitly call the superclass super(ImmutablePoint, self).__setattr__('x', x) super(ImmutablePoint, self).__setattr__('y', y) The standard library helper [https://docs.python.org/3.3/library/collections.html#collections.namedtuple namedtuple] creates simple immutable classes: Point = collections.namedtuple('Point', ['x', 'y']) is roughly equivalent to the above, plus some tuple-like features. JavaScriptIn JavaScript, some built-in types (numbers, strings) are immutable, but custom objects are generally mutable. function doSomething(x) { /* does changing x here change the original? */ }; var str = 'a string'; var obj = { an: 'object' }; doSomething(str); // strings, numbers and bool types are immutable, function gets a copy doSomething(obj); // objects are passed in by reference and are mutable inside function doAnotherThing(str, obj); // `str` has not changed, but `obj` may have. To simulate immutability in an object, one may define properties as read-only (writable: false). var obj = {}; Object.defineProperty(obj, 'foo', { value: 'bar', writable: false }); obj.foo = 'bar2'; // silently ignored However, the approach above still lets new properties be added. Alternatively, one may use [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze Object.freeze] to make existing objects immutable. var obj = { foo: 'bar' }; Object.freeze(obj); obj.foo = 'bars'; // cannot edit property, silently ignored obj.foo2 = 'bar2'; // cannot add property, silently ignored The use of immutable state has become a rising trend in JavaScript since the introduction of React, which favours Flux-like state management patterns such as Redux.[9] RacketRacket substantially diverges from other Scheme implementations by making its core pair type ("cons cells") immutable. Instead, it provides a parallel mutable pair type, via (struct foo1 (x y)) ; all fields immutable (struct foo2 (x [y #:mutable])) ; one mutable field (struct foo3 (x y) #:mutable) ; all fields mutable The language also supports immutable hash tables, implemented functionally, and immutable dictionaries. ScalaIn Scala, any entity (narrowly, a binding) can be defined as mutable or immutable: in the declaration, one can use For example, the following code snippet: val maxValue = 100 var currentValue = 1 defines an immutable entity By default, collection classes such as See also
ReferencesThis article contains some material from the Perl Design Patterns Book1. ^{{cite web|url=http://www.oxfordlearnersdictionaries.com/definition/english/immutable|title=immutable adjective - Definition, pictures, pronunciation and usage notes - Oxford Advanced Learner's Dictionary at OxfordLearnersDictionaries.com|website=www.oxfordlearnersdictionaries.com}} 2. ^1 2 Goetz et al. Java Concurrency in Practice. Addison Wesley Professional, 2006, Section 3.4. Immutability 3. ^{{cite web | url = http://www.javaranch.com/journal/2003/04/immutable.htm | title = Mutable and Immutable Objects: Make sure methods can't be overridden. | author = David O'Meara | date = April 2003 | work = Java Ranch | publisher = | quote = The preferred way is to make the class final. This is sometimes referred to as "Strong Immutability". It prevents anyone from extending your class and accidentally or deliberately making it mutable. | accessdate = 2012-05-14}} 4. ^{{cite web|url=https://docs.python.org/release/3.0/library/functions.html#bytearray|title=Built-in Functions — Python v3.0 documentation|website=docs.python.org}} 5. ^1 [https://dlang.org/spec/const3.html D Language Specification § 18] 6. ^[https://dlang.org/spec/arrays.html#strings D Language Specifcation § 12.16] (The terms array and slice are used interchangably.) 7. ^{{cite web|url=http://javarevisited.blogspot.co.uk/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html |title=How to create Immutable Class and Object in Java – Tutorial Example |publisher=Javarevisited.blogspot.co.uk |date=2013-03-04 |accessdate=2014-04-14}} 8. ^{{cite web | url=http://www.javapractices.com/topic/TopicAction.do?Id=29 | title=Immutable objects | publisher=javapractices.com | accessdate=November 15, 2012}} 9. ^{{cite web | website=Desalasworks | title=Immutability in JavaScript: A Contrarian View | url=http://desalasworks.com/article/immutability-in-javascript-a-contrarian-view/}} 10. ^{{cite web|url=http://www.scala-lang.org/docu/files/collections-api/collections_12.html |title=Scala 2.8 Collections API – Concrete Immutable Collection Classes |publisher=Scala-lang.org |date= |accessdate=2014-04-14}} External links{{Wiktionary|mutable}}
8 : Object (computer science)|Functional programming|Articles with example C++ code|Articles with example Java code|Articles with example Perl code|Articles with example Python code|Articles with example Racket code|Functional data structures |
随便看 |
|
开放百科全书收录14589846条英语、德语、日语等多语种百科知识,基本涵盖了大多数领域的百科知识,是一部内容自由、开放的电子版国际百科全书。