Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

Immutable object

From Wikipedia, the free encyclopedia
(Redirected fromImmutable value)
Object whose state cannot be modified after it is created
"Immutable" and "Immutability" redirect here. For the Christian doctrine, seeImmutability (theology). For the album, seeImmutable (album). For the crypto gaming company, seeImmutable Pty Ltd.

Inobject-oriented (OO) andfunctional programming, animmutable object (unchangeable[1] object) is anobject whosestate cannot be modified after it is created.[2] This is in contrast to amutable object (changeable object), which can be modified after it is created.[3] 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 usesmemoization 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 inherentlythread-safe.[2] Other benefits are that they are simpler to understand and reason about and offer higher security than mutable objects.[2]

Concepts

[edit]

Immutable variables

[edit]

Inimperative programming, values held inprogram variables whose content never changes are known asconstants to differentiate them from variables that could be altered during execution. Examples include conversion factors from meters to feet, or the value ofpi 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 immutability

[edit]

Sometimes, one talks of certainfields 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 calledstrongly immutable.[4] 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.const inC++,final inJava) that designates the field as immutable. Some languages reverse it: inOCaml, fields of an object or record are by default immutable, and must be explicitly marked withmutable to be so.

References to objects

[edit]

In mostobject-oriented languages, objects can be referred to usingreferences. Some examples of such languages areJava,C++,C#,VB.NET, and manyscripting languages, such asPerl,Python, andRuby. In this case, it matters whether the state of an object can vary when objects are shared via references.

Referencing vs copying objects

[edit]

If an object is known to be immutable, it is preferred to create areference of it instead of copying the entire object. This is done to conserve memory by preventing data duplication and avoid calls to constructors and destructors; it also results in 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. Theobserver pattern is an alternative technique for handling changes to mutable objects.

Copy-on-write

[edit]

A technique that blends the advantages ofmutable andimmutable objects, and is supported directly in almost all modern hardware, iscopy-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 invirtual memory systems because it allows them to save memory space while still correctly handling anything an application program might do.

Interning

[edit]

The practice of always using references in place of copies of equal objects is known asinterning. 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 automaticallyinterns 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 afast path case improvement when the objects are equal and use the same reference.) Interning is generally only useful for immutable objects.

Thread safety

[edit]

Immutable 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 morethread-safe than mutable objects.

Violating immutability

[edit]

Immutability does not imply that the object as stored in the computer'smemory is unwriteable. Rather, immutability is acompile-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 violatingconst correctness inC orC++).

Language-specific details

[edit]

InPython,Java[5]: 80  and the.NET Framework, strings are immutable objects. Both Java and the .NET Framework have mutable versions of string. In Java[5]: 84  these areStringBuffer andStringBuilder (mutable versions of JavaString) and in .NET this isStringBuilder (mutable version of .NetString).Python 3 has a mutable string (bytes) variant, namedbytearray.[6]

Additionally, all of theprimitive wrapper classes in Java are immutable.

Similar patterns are theImmutable Interface andImmutable Wrapper.

In purefunctional programming languages it is not possible to create mutable objects without extending the language (e.g. via a mutable references library or aforeign function interface), so all objects are immutable.

Ada

[edit]

InAda, any object is declared eithervariable (i.e. mutable; typically the implicit default), orconstant (i.e. immutable) via theconstant keyword.

typeSome_typeisnewInteger;-- could be anything more complicatedx:constantSome_type:=1;-- immutabley:Some_type;-- mutable

Subprogram parameters are immutable in thein mode, and mutable in thein out andout modes.

procedureDo_it(a:inInteger;b:inoutInteger;c:outInteger)isbegin-- a is immutableb:=b+a;c:=a;endDo_it;

C#

[edit]

InC# you can enforce immutability of the fields of a class with thereadonly statement.[7]: 239 By enforcing all the fields as immutable, you obtain an immutable type.

classAnImmutableType{publicreadonlydouble_value;publicAnImmutableType(doublex){_value=x;}publicAnImmutableTypeSquare(){returnnewAnImmutableType(_value*_value);}}

C# have records which are immutable.[8][9]

recordPerson(stringFirstName,stringLastName);

C++

[edit]

In C++, aconst-correct implementation ofCart would allow the user to create instances of the class and then use them as eitherconst (immutable) or mutable, as desired, by providing two different versions of theitems() method. (Notice that in C++ it is not necessary — and in fact impossible — to provide a specialized constructor forconst instances.)

classCart{public:Cart(std::vector<Item>items):items_(items){}std::vector<Item>&items(){returnitems_;}conststd::vector<Item>&items()const{returnitems_;}intComputeTotalCost()const{/* return sum of the prices */}private:std::vector<Item>items_;};

Note that, when there is a data member that is a pointer or reference to another object, then it is possible to mutate the object pointed to or referenced only within a non-const method.

C++ also provides abstract (as opposed to bitwise) immutability via themutable keyword, which lets amember variable be changed from within aconst method.

classCart{public:Cart(std::vector<Item>items):items_(items){}conststd::vector<Item>&items()const{returnitems_;}intComputeTotalCost()const{if(total_cost_){return*total_cost_;}inttotal_cost=0;for(constauto&item:items_){total_cost+=item.Cost();}total_cost_=total_cost;returntotal_cost;}private:std::vector<Item>items_;mutablestd::optional<int>total_cost_;};

D

[edit]

InD, there exist twotype qualifiers,const andimmutable, for variables that cannot be changed.[10] Unlike C++'sconst, Java'sfinal, and C#'sreadonly, they are transitive and recursively apply to anything reachable through references of such a variable. The difference betweenconst andimmutable is what they apply to:const is a property of the variable: there might legally exist mutable references to referred value, i.e. the value can actually change. In contrast,immutable is a property of the referred value: the value and anything transitively reachable from it cannot change (without breaking the type system, leading toundefined behavior). Any reference of that value must be markedconst orimmutable. Basically for any unqualified typeT,const(T) is the disjoint union ofT (mutable) andimmutable(T).

classC{/*mutable*/ObjectmField;constObjectcField;immutableObjectiField;}

For a mutableC object, itsmField can be written to. For aconst(C) object,mField cannot be modified, it inheritsconst;iField is still immutable as it is the stronger guarantee. For animmutable(C), all fields are immutable.

In a function like this:

voidfunc(Cm,constCc,immutableCi){/* inside the braces */}

Inside the braces,c might refer to the same object asm, so mutations tom could indirectly changec as well. Also,c might refer to the same object asi, but since the value then is immutable, there are no changes. However,m andi cannot legally refer to the same object.

In the language of guarantees, mutable has no guarantees (the function might change the object),const is an outward-only guarantee that the function will not change anything, andimmutable is a bidirectional guarantee (the function will not change the value and the caller must not change it).

Values that areconst orimmutable must be initialized by direct assignment at the point ofdeclaration or by aconstructor.

Becauseconst parameters forget if the value was mutable or not, a similar construct,inout, acts, in a sense, as a variable for mutability information.A function of typeconst(S) function(const(T)) returnsconst(S) typed values for mutable, const and immutable arguments. In contrast, a function of typeinout(S) function(inout(T)) returnsS for mutableT arguments,const(S) forconst(T) values, andimmutable(S) forimmutable(T) values.

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."[10] 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 typestring is an alias forimmutable(char)[], i.e. a typed slice of memory of immutable characters.[11] Making substrings is cheap, as it just copies and modifies a pointer and a length filed, and safe, as the underlying data cannot be changed. Objects of typeconst(char)[] can refer to strings, but also to mutable buffers.

Making a shallow copy of a const or immutable value removes the outer layer of immutability: Copying an immutable string (immutable(char[])) returns a string (immutable(char)[]). The immutable pointer and length are being copied and the copies are mutable. The referred data has not been copied and keeps its qualifier, in the exampleimmutable. It can be stripped by making a depper copy, e.g. using thedup function.

Java

[edit]

A classic example of an immutable object is an instance of the JavaString class

Strings="ABC";s.toLowerCase();// This accomplishes nothing!

The methodtoLowerCase() does not change the data "ABC" thats contains. Instead, a new String object is instantiated and given the data "abc" during its construction. A reference to this String object is returned by thetoLowerCase() method. To make the Strings contain the data "abc", a different approach is needed:

s=s.toLowerCase();

Now the Strings references a new String object that contains "abc". There is nothing in the syntax of thedeclaration of the class String that enforces it as immutable; rather, none of the String class's methods ever affect the data that a String object contains, thus making it immutable.

The keywordfinal (detailed article) is used in implementing immutable primitive types and object references,[12] but it cannot, by itself, makethe objects themselves immutable. See below examples:

Primitive type variables (int,long,short, etc.) can be reassigned after being defined. This can be prevented by usingfinal.

inti=42;//int is a primitive typei=43;// OKfinalintj=42;j=43;// does not compile. j is final so can't be reassigned

Reference types cannot be made immutable just by using thefinal keyword.final only prevents reassignment.

finalMyObjectm=newMyObject();//m is of reference typem.data=100;// OK. We can change state of object m (m is mutable and final doesn't change this fact)m=newMyObject();// does not compile. m is final so can't be reassigned

Primitive wrappers (Integer,Long,Short,Double,Float,Character,Byte,Boolean) are also all immutable. Immutable classes can be implemented by following a few simple guidelines.[13]

JavaScript

[edit]

InJavaScript, all primitive types (Undefined, Null, Boolean, Number, BigInt, String, Symbol) are immutable, but custom objects are generally mutable.

functiondoSomething(x){/* does changing x here change the original? */};varstr='a string';varobj={an:'object'};doSomething(str);// strings, numbers and bool types are immutable, function gets a copydoSomething(obj);// objects are passed in by reference and are mutable inside functiondoAnotherThing(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).

varobj={};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 useObject.freeze to make existing objects immutable.

varobj={foo:'bar'};Object.freeze(obj);obj.foo='bars';// cannot edit property, silently ignoredobj.foo2='bar2';// cannot add property, silently ignored

With the implementation ofECMA262, JavaScript has the ability to create immutable references that cannot be reassigned. However, using aconst declaration doesn't mean that value of the read-only reference is immutable, just that the name cannot be assigned to a new value.

constALWAYS_IMMUTABLE=true;try{ALWAYS_IMMUTABLE=false;}catch(err){console.log("Can't reassign an immutable reference.");}constarr=[1,2,3];arr.push(4);console.log(arr);// [1, 2, 3, 4]

The use of immutable state has become a rising trend in JavaScript since the introduction ofReact, which favours Flux-like state management patterns such asRedux.[14]

Perl

[edit]

InPerl, one can create an immutable class with the Moo library by simply declaring all the attributes read only:

packageImmutable;useMoo;hasvalue=>(is=>'ro',# read onlydefault=>'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):

packageImmutable;usestrict;usewarnings;usebaseqw(Class::Accessor);# create read-only accessors__PACKAGE__->mk_ro_accessors(qw(value));useHash::Util'lock_hash';subnew{my$class=shift;return$classifref($class);die"Arguments to new must be key => value pairs\n"unless(@_%2==0);my%defaults=(value=>'data',);my$obj={%defaults,@_,};bless$obj,$class;# prevent modification of the object datalock_hash%$obj;}1;

Or, with a manually written accessor:

packageImmutable;usestrict;usewarnings;useHash::Util'lock_hash';subnew{my$class=shift;return$classifref($class);die"Arguments to new must be key => value pairs\n"unless(@_%2==0);my%defaults=(value=>'data',);my$obj={%defaults,@_,};bless$obj,$class;# prevent modification of the object datalock_hash%$obj;}# read-only accessorsubvalue{my$self=shift;if(my$new_value=shift){# trying to set a new valuedie"This object cannot be modified\n";}else{return$self->{value}}}1;

PHP

[edit]

InPHP have readonly properties since version 8.1 and readonly classes since version 8.2.[15][16]

readonlyclassBlogData{publicstring$title;publicStatus$status;publicfunction__construct(string$title,Status$status){$this->title=$title;$this->status=$status;}}

Python

[edit]

InPython, some built-in types (numbers, Booleans, strings, tuples, frozensets) are immutable, but custom classes are generally mutable. To simulate immutability in a class, one could override attribute setting and deletion to raise exceptions:

classImmutablePoint:"""An immutable class with two attributes 'x' and 'y'."""__slots__=['x','y']def__setattr__(self,*args):raiseTypeError("Can not modify immutable instance.")__delattr__=__setattr__def__init__(self,x,y):# We can no longer use self.value = value to store the instance data# so we must explicitly call the superclasssuper().__setattr__('x',x)super().__setattr__('y',y)

The standard library helperscollections.namedtuple andtyping.NamedTuple, available from Python 3.6 onward, create simple immutable classes. The following example is roughly equivalent to the above, plus some tuple-like features:

fromtypingimportNamedTupleimportcollectionsPoint=collections.namedtuple('Point',['x','y'])# the following creates a similar namedtuple to the aboveclassPoint(NamedTuple):x:inty:int

Introduced in Python 3.7,dataclasses allow developers to emulate immutability withfrozen instances. If a frozen dataclass is built,dataclasses will override__setattr__() and__delattr__() to raiseFrozenInstanceError if invoked.

fromdataclassesimportdataclass@dataclass(frozen=True)classPoint:x:inty:int

Racket

[edit]

Racket substantially diverges from otherScheme implementations by making its core pair type ("cons cells") immutable. Instead, it provides a parallel mutable pair type, viamcons,mcar,set-mcar! etc. In addition, many immutable types are supported, for example, immutable strings and vectors, and these are used extensively. New structs are immutable by default, unless a field is specifically declared mutable, or the whole struct:

(structfoo1(xy)); all fields immutable(structfoo2(x[y#:mutable])); one mutable field(structfoo3(xy)#:mutable); all fields mutable

The language also supports immutable hash tables, implemented functionally, and immutable dictionaries.

Rust

[edit]

Rust'sownership system allows developers to declare immutable variables, and pass immutable references. By default, all variables and references are immutable. Mutable variables and references are explicitly created with themut keyword.

Constant items in Rust are always immutable.

// constant items are always immutableconstALWAYS_IMMUTABLE:bool=true;structObject{x:usize,y:usize,}fnmain(){// explicitly declare a mutable variableletmutmutable_obj=Object{x:1,y:2};mutable_obj.x=3;// okayletmutable_ref=&mutmutable_obj;mutable_ref.x=1;// okayletimmutable_ref=&mutable_obj;immutable_ref.x=3;// error E0594// by default, variables are immutableletimmutable_obj=Object{x:4,y:5};immutable_obj.x=6;// error E0596letmutable_ref2=&mutimmutable_obj;// error E0596letimmutable_ref2=&immutable_obj;immutable_ref2.x=6;// error E0594}

Scala

[edit]

InScala, any entity (narrowly, a binding) can be defined as mutable or immutable: in the declaration, one can useval (value) for immutable entities andvar (variable) for mutable ones. Note that even though an immutable binding can not be reassigned, it may still refer to a mutable object and it is still possible to call mutating methods on that object: thebinding is immutable, but the underlyingobject may be mutable.

For example, the following code snippet:

valmaxValue=100varcurrentValue=1

defines an immutable entitymaxValue (the integer type is inferred at compile-time) and a mutable entity namedcurrentValue.

By default, collection classes such asList andMap are immutable, so update-methods return a new instance rather than mutating an existing one. While this may sound inefficient, the implementation of these classes and their guarantees of immutability mean that the new instance can re-use existing nodes, which, especially in the case of creating copies, is very efficient.[17][better source needed]

See also

[edit]

References

[edit]

This article contains some material from thePerl Design Patterns Book

  1. ^"immutable adjective - Definition, pictures, pronunciation and usage notes - Oxford Advanced Learner's Dictionary at OxfordLearnersDictionaries.com".www.oxfordlearnersdictionaries.com.
  2. ^abcGoetz et al.Java Concurrency in Practice. Addison Wesley Professional, 2006, Section 3.4. Immutability
  3. ^"6.005 — Software Construction".
  4. ^David O'Meara (April 2003)."Mutable and Immutable Objects: Make sure methods can't be overridden".Java Ranch. Retrieved2012-05-14.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.
  5. ^abBloch, Joshua (2018)."Effective Java: Programming Language Guide" (third ed.). Addison-Wesley.ISBN 978-0134685991.
  6. ^"Built-in Functions — Python v3.0 documentation".docs.python.org.
  7. ^Skeet, Jon (23 March 2019).C# in Depth. Manning.ISBN 978-1617294532.
  8. ^"Use record types - C# tutorial - C#".learn.microsoft.com. 14 November 2023. Retrieved23 February 2024.
  9. ^"Records - C# reference - C#".learn.microsoft.com. 25 May 2023. Retrieved23 February 2024.
  10. ^abD Language Specification § 18
  11. ^D Language Specification § 12.16 (The termsarray andslice are used interchangeably.)
  12. ^"How to create Immutable Class and Object in Java – Tutorial Example". Javarevisited.blogspot.co.uk. 2013-03-04. Retrieved2014-04-14.
  13. ^"Immutable objects". javapractices.com. RetrievedNovember 15, 2012.
  14. ^"Immutability in #".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. ^"Scala 2.8 Collections API – Concrete Immutable Collection Classes". Scala-lang.org. Retrieved2014-04-14.

External links

[edit]
Look upmutable in Wiktionary, the free dictionary.
Retrieved from "https://en.wikipedia.org/w/index.php?title=Immutable_object&oldid=1271563598"
Categories:
Hidden categories:

[8]ページ先頭

©2009-2025 Movatter.jp