Из Википедии, свободной энциклопедии
  (Перенаправлен с Immutable )
Перейти к навигации Перейти к поиску

В объектно-ориентированном и функциональном программировании неизменяемый объект (unchangeable [1] объект) - это объект , состояние которого не может быть изменено после его создания. [2] В этом отличие от изменяемого объекта (изменяемого объекта), который может быть изменен после его создания. [3] В некоторых случаях объект считается неизменным, даже если некоторые внутренние атрибуты меняются, но состояние объекта кажется неизменным с внешней точки зрения. Например, объект, который использует мемоизацию для кэширования результатов дорогостоящих вычислений, все еще может считаться неизменяемым объектом.

Строки и другие конкретные объекты обычно выражаются как неизменяемые объекты, чтобы улучшить читаемость и эффективность выполнения в объектно-ориентированном программировании . Неизменяемые объекты также полезны, потому что они по своей природе потокобезопасны . [2] Другие преимущества заключаются в том, что они проще для понимания и рассуждений, а также обеспечивают более высокий уровень безопасности, чем изменяемые объекты. [2]

Концепции [ править ]

Неизменяемые переменные [ править ]

В императивном программировании значения, хранящиеся в переменных программы , содержимое которых никогда не изменяется, называются константами, чтобы отличать их от переменных, которые могут быть изменены во время выполнения. Примеры включают коэффициенты преобразования из метров в футы или значение числа пи с точностью до нескольких десятичных знаков.

Поля только для чтения могут вычисляться при запуске программы (в отличие от констант, которые известны заранее), но никогда не изменяются после их инициализации.

Слабая и сильная неизменяемость [ править ]

Иногда говорят о неизменности определенных полей объекта. Это означает, что нет возможности изменить эти части состояния объекта, даже если другие части объекта могут быть изменяемыми ( слабо неизменяемыми ). Если все поля неизменяемы, объект неизменен. Если весь объект не может быть расширен другим классом, объект называется строго неизменяемым . [4] Это могло бы, например, помочь явным образом обеспечить соблюдение определенных инвариантов о том, что определенные данные в объекте остаются неизменными в течение всего времени существования объекта. В некоторых языках это делается с помощью ключевого слова (например, constв C ++ , finalв Java), который обозначает поле как неизменяемое. В некоторых языках это происходит наоборот: в OCaml поля объекта или записи по умолчанию неизменяемы и для этого должны быть явно отмечены значком mutable.

Ссылки на объекты [ править ]

В большинстве объектно-ориентированных языков на объекты можно ссылаться . Некоторыми примерами таких языков являются Java , C ++ , C # , VB.NET и многие языки сценариев , такие как Perl , Python и Ruby . В этом случае имеет значение, может ли состояние объекта меняться при совместном использовании объектов через ссылки.

Ссылки и копирование объектов [ править ]

Если известно, что объект неизменен, рекомендуется создать ссылку на него, а не копировать весь объект. Это сделано для экономии памяти, предотвращая дублирование данных и избегая вызовов конструкторов и деструкторов; это также приводит к потенциальному увеличению скорости выполнения.

Технику копирования ссылок намного сложнее использовать для изменяемых объектов, потому что, если какой-либо пользователь ссылки на изменяемый объект изменяет ее, все другие пользователи этой ссылки видят это изменение. Если это не желаемый эффект, может быть сложно уведомить других пользователей, чтобы они ответили правильно. В таких ситуациях защитное копирование всего объекта, а не ссылки, обычно является простым, но дорогостоящим решением. Шаблон наблюдатель является альтернативным методом для обработки изменений в изменяемые объекты.

Копирование при записи [ править ]

Техника, которая сочетает в себе преимущества изменяемых и неизменяемых объектов и поддерживается напрямую почти всем современным оборудованием, - это копирование при записи.(КОРОВА). Используя этот метод, когда пользователь просит систему скопировать объект, вместо этого он просто создает новую ссылку, которая по-прежнему указывает на тот же объект. Как только пользователь пытается изменить объект с помощью определенной ссылки, система делает реальную копию, применяет к ней модификацию и устанавливает ссылку для ссылки на новую копию. Остальные пользователи не затронуты, потому что они по-прежнему ссылаются на исходный объект. Следовательно, в COW все пользователи имеют изменяемую версию своих объектов, хотя в случае, если пользователи не изменяют свои объекты, сохраняются преимущества неизменяемых объектов в экономии места и скорости. Копирование при записи популярно в системах виртуальной памяти , поскольку позволяет им экономить пространство памяти, при этом правильно обрабатывая все, что может делать прикладная программа.

Стажировка [ править ]

Практика всегда использования ссылок вместо копий одинаковых объектов известна как интернирование . Если используется интернирование, два объекта считаются равными тогда и только тогда, когда их ссылки, обычно представленные в виде указателей или целых чисел, равны. Некоторые языки делают это автоматически: например, Python автоматически обрабатывает короткие строки . Если алгоритм, реализующий интернирование, гарантированно будет делать это во всех возможных случаях, то сравнение объектов на равенство сводится к сравнению их указателей - существенный выигрыш в скорости в большинстве приложений. (Даже если не гарантируется, что алгоритм будет всеобъемлющим, все же существует возможность быстрого пути улучшение случая, когда объекты равны и используют одну и ту же ссылку.) Интернирование обычно полезно только для неизменяемых объектов.

Безопасность потоков [ править ]

Неизменяемые объекты могут быть полезны в многопоточных приложениях. Несколько потоков могут воздействовать на данные, представленные неизменяемыми объектами, не заботясь об изменении данных другими потоками. Поэтому неизменяемые объекты считаются более потокобезопасными, чем изменяемые объекты.

Нарушение неизменности [ править ]

Неизменяемость не означает, что объект, хранящийся в памяти компьютера, не подлежит перезаписи. Скорее, неизменяемость - это конструкция времени компиляции, которая указывает, что программист может делать через обычный интерфейс объекта, не обязательно то, что он может сделать абсолютно (например, обходя систему типов или нарушая корректность констант в C или C ++ ).

Сведения для конкретного языка [ править ]

В Python , Java и .NET Framework строки являются неизменяемыми объектами. И Java, и .NET Framework имеют изменяемые версии строки. В Java это StringBufferи StringBuilder(изменяемые версии Java String), а в .NET - это StringBuilder(изменяемая версия .Net String). Python 3 имеет изменяемый строковый (байтовый) вариант с именем bytearray. [5]

Кроме того, все примитивные классы-оболочки в Java неизменяемы.

Аналогичные шаблоны - это неизменяемый интерфейс и неизменяемая оболочка .

В чистых языках функционального программирования невозможно создавать изменяемые объекты без расширения языка (например, через библиотеку изменяемых ссылок или интерфейс внешней функции ), поэтому все объекты неизменяемы.

Ада [ править ]

В Ada любой объект объявляется либо переменной (т. Е. Изменяемым; обычно неявное значение по умолчанию), либо constant(т. Е. Неизменяемым) с помощью constantключевого слова.

 тип  Some_type  - это  новое  целое число ;  - может быть что угодно более сложное  x :  constant  Some_type : =  1 ;  - неизменяемый  y :  Some_type ;  - изменчивый

Параметры подпрограмм являются неизменными в в режиме, и изменяемых в в из и из режимов.

 процедура  Do_it ( a : in  Integer ;  b : in  out  Integer ;  c : out  Integer )  is  begin  - a неизменяема  b : =  b  +  a ;  с : =  а ;  конец  Do_it ;

C # [ править ]

В C # вы можете обеспечить неизменность полей класса с помощью readonlyоператора. Установив все поля как неизменяемые, вы получите неизменяемый тип.

класс  AnImmutableType {  общественного  чтения  двойной  _value ;  общедоступный  AnImmutableType ( двойной  x )  {  _value  =  x ;  }  public  AnImmutableType  Square ()  {  вернуть  новый  AnImmutableType ( _value  *  _value );  } }

C ++ [ править ]

В C ++ константно-правильная реализация Cartпозволит пользователю объявлять новые экземпляры класса либо как const(неизменяемые), либо как изменяемые, по желанию, путем предоставления двух разных версий getItems()метода. (Обратите внимание, что в C ++ нет необходимости - и фактически невозможно - предоставлять специализированный конструктор для constэкземпляров.)

class  Cart  {  public :  Cart ( std :: vector < Item >  items ) :  items_ ( std :: move ( items ))  {} std :: vector < Item > &  items ()  {  return  items_ ;  }  const  std :: vector < Item > &  items ()  const  {  return  items_ ;  } int  ComputeTotalCost ()  const  {  / * возвращает сумму цен * /  } частный :  std :: vector < Item >  items_ ; };

Обратите внимание, что если есть поле, которое является указателем или ссылкой на другой объект, тогда все еще может быть возможно изменить объект, на который указывает такой указатель или ссылка в константном методе, без нарушения константной корректности. Можно утверждать, что в таком случае объект на самом деле не является неизменным.

C ++ также обеспечивает абстрактную (в отличие от побитовой) неизменяемость с помощью mutableключевого слова, которое позволяет изменять переменную-член внутри constметода.

class  Cart  {  public :  Cart ( std :: vector < Item >  items ) :  items_ ( std :: move ( items ))  {} const  std :: vector < Item > &  items ()  const  {  return  items_ ;  } int  ComputeTotalCost ()  const  {  если  ( total_cost_ )  {  return  * total_cost_ ;  } int  total_cost  =  0 ;  for  ( const  auto &  item  :  items_ )  {  total_cost  + =  item . Стоимость ();  }  total_cost_  =  total_cost ;  вернуть  total_cost ;  } частный :  std :: vector < Item >  items_ ;  изменяемый  std :: optional < int >  total_cost_ ; };

D [ править ]

В D , существует два отборочных типа , constи immutableдля переменных , которые не могут быть изменены. [6] В отличие от языков C ++ const, Java finalи C # readonly, они транзитивны и рекурсивно применяются ко всему, что доступно через ссылки на такую ​​переменную. Разница между constи immutableзаключается в том, к чему они применяются: constэто свойство переменной: юридически могут существовать изменяемые ссылки на указанное значение, т.е. значение может фактически измениться. Напротив, immutableэто свойство упомянутого значения: значение и все, что транзитивно достижимо из него, не может измениться (без нарушения системы типов, что приводит к неопределенному поведению.). Любая ссылка на это значение должна быть помечена constили immutable. В основном для любого неквалифицированного типа T, const(T)является объединением непересекающихся T(изменяемый) и immutable(T).

class  C  {  / * изменчивый * /  Object  mField ;  const  Object  cField ;  неизменяемый  объект  iField ; }

Для изменяемого Cобъекта в него mFieldможно записать. Для const(C)объекта, mFieldне может быть изменен, он наследует const; iFieldпо-прежнему неизменен, поскольку это более сильная гарантия. Для объекта immutable(C)все поля неизменяемы.

В такой функции:

void  func ( C  m ,  const  C  c ,  неизменяемый  C  i ) {  / * внутри фигурных скобок * /  }

Внутри фигурных скобок cможет обозначаться тот же объект, что и m, поэтому мутации mмогут также косвенно изменяться c. Кроме того, cможет относиться к тому же объекту, что и i, но, поскольку значение неизменяемо, изменений нет. Однако mи iне может юридически относиться к одному и тому же объекту.

На языке гарантий mutable не имеет никаких гарантий (функция может изменить объект), constявляется внешней гарантией того, что функция ничего не изменит, и immutableявляется двунаправленной гарантией (функция не изменит значение, и вызывающий должен не меняй это).

Значения, которые инициализируются constили immutableдолжны быть инициализированы прямым присваиванием в точке объявления или конструктором .

Поскольку constпараметры забывают, было ли значение изменяемым или нет, аналогичная конструкция inout, действует, в некотором смысле, как переменная для информации об изменчивости. Функция типа const(S) function(const(T))возвращает const(S)типизированные значения для изменяемых, константных и неизменяемых аргументов. Напротив, функция типа inout(S) function(inout(T))возвращает Sдля изменяемых Tаргументов, const(S)для const(T)значений и immutable(S)для immutable(T)значений.

Приведение неизменяемых значений к изменяемым приводит к неопределенному поведению при изменении, даже если исходное значение происходит из изменяемого источника. Преобразование изменяемых значений в неизменяемые может быть законным, если после этого не останется изменяемых ссылок. «Выражение может быть преобразовано из изменяемого (...) в неизменяемое, если выражение уникально и все выражения, на которые оно транзитивно ссылается, являются уникальными или неизменяемыми». [6] Если компилятор не может доказать уникальность, преобразование может быть выполнено явно, и программист должен убедиться, что не существует изменяемых ссылок.

Тип string- это псевдоним immutable(char)[], то есть типизированный фрагмент памяти неизменяемых символов. [7] Создание подстрок дешево, так как оно просто копирует и изменяет указатель и поле длины, и безопасно, поскольку лежащие в основе данные не могут быть изменены. Объекты типа const(char)[]могут относиться к строкам, но также и к изменяемым буферам.

Создание неглубокой копии константного или неизменяемого значения удаляет внешний слой неизменяемости: копирование неизменяемой строки ( immutable(char[])) возвращает строку ( immutable(char)[]). Неизменяемый указатель и длина копируются, и копии изменяемы. Указанные данные не были скопированы и в этом примере сохраняют свой квалификатор immutable. Его можно удалить, сделав более глубокую копию, например, с помощью dupфункции.

Java [ править ]

Классическим примером неизменяемого объекта является экземпляр Stringкласса Java.

Строка  s  =  "ABC" ; с . toLowerCase ();

Метод toLowerCase()не изменяет данные, которые sсодержат "ABC" . Вместо этого создается новый объект String, которому во время его создания предоставляются данные «abc». Ссылка на этот объект String возвращается toLowerCase()методом. Чтобы строка sсодержала данные «abc», необходим другой подход:

s  =  s . toLowerCase ();

Теперь String sссылается на новый объект String, содержащий «abc». В синтаксисе объявления класса String нет ничего, что считало бы его неизменным; скорее, ни один из методов класса String никогда не влияет на данные, содержащиеся в объекте String, что делает его неизменяемым.

Ключевое слово final( подробная статья ) используется для реализации неизменяемых примитивных типов и ссылок на объекты [8], но само по себе оно не может сделать сами объекты неизменяемыми. См. Примеры ниже:

Примитивный переменные типа ( int, long, shortи т.д.) могут быть переназначены после того , как определены. Этого можно избежать, используя final.

int  i  =  42 ;  // int - примитивный тип i  =  43 ;  // В ПОРЯДКЕфинальный  int  j  =  42 ; j  =  43 ;  // не компилируется. j является окончательным, поэтому его нельзя переназначить

Ссылочные типы нельзя сделать неизменяемыми с помощью finalключевого слова. finalтолько предотвращает переназначение.

последний  MyObject  m  =  новый  MyObject ();  // m имеет ссылочный тип m . данные  =  100 ;  // В ПОРЯДКЕ. Мы можем изменить состояние объекта m (m является изменяемым, и final не меняет этого факта) m  =  new  MyObject ();  // не компилируется. m является окончательным, поэтому не может быть переназначен

Примитивные упаковщики ( Integer, Long, Short, Double, Float, Character, Byte, Boolean) также все неизменны. Неизменяемые классы можно реализовать, следуя нескольким простым рекомендациям. [9]

Perl [ править ]

В Perl можно создать неизменяемый класс с библиотекой Moo, просто объявив все атрибуты только для чтения:

пакет  Неизменяемый ; используйте  Moo ;has  value  =>  (  is  =>  'ro' ,  # только для чтения по  умолчанию  =>  'data' ,  # можно переопределить, задав конструктору  # значение: Immutable-> new (value => 'something else'); ) ;1 ;

Для создания неизменяемого класса требовалось два шага: во-первых, создание аксессоров (автоматически или вручную), предотвращающих изменение атрибутов объекта, и, во-вторых, предотвращение прямого изменения данных экземпляра экземпляров этого класса (обычно это хранилось в хеш-коде). ссылку и может быть заблокирован с помощью функции Hash :: Util lock_hash):

пакет  Неизменяемый ; используйте  строгий ; использовать  предупреждения ; использовать  базовый  qw (Class :: Accessor) ; # создать средства доступа только для чтения __PACKAGE__ -> mk_ro_accessors ( qw (value) ); используйте  Hash :: Util  'lock_hash' ;sub  новый  {  мой  $ class  =  shift ;  вернуть  $ class,  если  ref ( $ class );  die  "Аргументы для нового должны быть парами ключ => значение \ n",  если  ( @_  %  2  ==  0 );  мои  % defaults  =  (  значение  =>  'данные' ,  );  мой  $ obj  =  {  % по умолчанию ,  @_ ,  };  благослови  $ obj ,  $ class ; # запретить модификацию данных объекта  lock_hash  % $ obj ; } 1 ;

Или с помощью написанного вручную аксессуара:

пакет  Неизменяемый ; используйте  строгий ; использовать  предупреждения ; используйте  Hash :: Util  'lock_hash' ;sub  новый  {  мой  $ class  =  shift ;  вернуть  $ class,  если  ref ( $ class );  die  "Аргументы для нового должны быть парами ключ => значение \ n",  если  ( @_  %  2  ==  0 );  мои  % defaults  =  (  значение  =>  'данные' ,  );  мой  $ obj  =  {  % по умолчанию ,  @_ ,  };  благослови  $ obj ,  $ class ; # запретить модификацию данных объекта  lock_hash  % $ obj ; }# Только для чтения аксессора югу  значения  {  мой  $ самого  =  сдвиг ;  if  ( my  $ new_value  =  shift )  {  # пытаюсь установить новое значение  die  "Этот объект нельзя изменить \ n" ;  }  else  {  return  $ self -> { значение }  } } 1 ;

Python [ править ]

В Python некоторые встроенные типы (числа, логические значения, строки, кортежи, замороженные наборы) неизменяемы, но пользовательские классы обычно изменяемы. Чтобы имитировать неизменяемость в классе, можно переопределить установку и удаление атрибута, чтобы вызвать исключения:

class  ImmutablePoint :  "" " Неизменяемый класс с двумя атрибутами 'x' и 'y'." "" __slots__  =  [ 'x' ,  'y' ] def  __setattr__ ( self ,  * args ):  raise  TypeError ( «Невозможно изменить неизменяемый экземпляр.» ) __delattr__  =  __setattr__ def  __init__ ( self ,  x ,  y ):  # Мы больше не можем использовать self.value = value для хранения данных экземпляра  # поэтому мы должны явно вызвать суперкласс  super () . __setattr__ ( 'x' ,  x )  super () . __setattr__ ( 'у' ,  у )

Стандартные помощники библиотеки collections.namedtupleи typing.NamedTuple, доступные начиная с Python 3.6, создают простые неизменяемые классы. Следующий пример примерно эквивалентен приведенному выше, плюс некоторые функции, похожие на кортежи:

от  ввода  import  NamedTuple импортировать  коллекцииPoint  =  коллекции . namedtuple ( 'Точка' ,  [ 'x' ,  'y' ])# следующее создает именованный кортеж, аналогичный указанному выше классу  Point ( NamedTuple ):  x :  int  y :  int

Представленный в Python 3.7, dataclassesпозволяет разработчикам эмулировать неизменяемость с помощью замороженных экземпляров . Если построен замороженный класс данных, dataclassesбудет переопределен __setattr__()и __delattr__()будет повышаться FrozenInstanceErrorпри вызове.

из  классов данных  импортировать  класс данных@dataclass ( замороженный = True ) класс  Точка :  x :  int  y :  int

JavaScript [ править ]

В JavaScript все примитивные типы (Undefined, Null, Boolean, Number, BigInt, String, Symbol) неизменны, но пользовательские объекты обычно изменяемы.

function  doSomething ( x )  {  / * изменение x здесь меняет оригинал? * /  }; var  str  =  'строка' ; var  obj  =  {  an :  'объект'  }; doSomething ( str );  // строки, числа и типы bool неизменяемы, функция получает копию doSomething ( obj );  // объекты передаются по ссылке и могут изменяться внутри function doAnotherThing ( str ,  obj );  // `str` не изменилась, но` obj` может измениться.

Чтобы имитировать неизменяемость объекта, можно определить свойства как доступные только для чтения (для записи: false).

var  obj  =  {}; Объект . defineProperty ( obj ,  'foo' ,  {  значение :  'bar' ,  доступно для записи :  false  }); OBJ . foo  =  'bar2' ;  // игнорируется молча

Однако описанный выше подход по-прежнему позволяет добавлять новые свойства. В качестве альтернативы можно использовать Object.freeze, чтобы сделать существующие объекты неизменяемыми.

var  obj  =  {  foo :  'bar'  }; Объект . заморозить ( obj ); OBJ . foo  =  'бары' ;  // невозможно редактировать свойство, игнорируется автоматически obj . foo2  =  'bar2' ;  // невозможно добавить свойство, игнорируется молча

С реализацией ECMA262 JavaScript имеет возможность создавать неизменяемые ссылки, которые нельзя переназначить. Однако использование constобъявления не означает, что значение ссылки только для чтения является неизменным, просто имя не может быть присвоено новому значению.

const  ALWAYS_IMMUTABLE  =  true ;попробуйте  {  ALWAYS_IMMUTABLE  =  false ; }  catch  ( err )  {  console . log ( "Невозможно переназначить неизменяемую ссылку." ); }const  arr  =  [ 1 ,  2 ,  3 ]; обр . толкать ( 4 ); консоль . журнал ( обр );  // [1, 2, 3, 4]

Использование неизменяемого состояния стало растущей тенденцией в JavaScript с момента появления React , который отдает предпочтение шаблонам управления состоянием, подобным Flux, таким как Redux . [10]

Ракетка [ править ]

Racket существенно отличается от других реализаций Схемы , делая свой тип базовой пары («cons-ячейки») неизменным. Вместо этого, он обеспечивает параллельный изменяемый тип пару, с помощью mcons, mcar, и set-mcar!т.д. Кроме того, многие неизменные типов поддерживаемых, например, неизменных строк и векторов, и они широко используются. Новые структуры неизменяемы по умолчанию, если только поле специально не объявлено изменяемым, или вся структура:

( struct  foo1  ( x  y ))  ; все поля неизменяемы ( struct  foo2  ( x  [ y  #: mutable ]))  ; одно изменяемое поле ( struct  foo3  ( x  y )  #: mutable )  ; все поля изменяемы

Язык также поддерживает неизменяемые хэш-таблицы, реализованные функционально, и неизменяемые словари.

Ржавчина [ править ]

Система владения Rust позволяет разработчикам объявлять неизменяемые переменные и передавать неизменяемые ссылки. По умолчанию все переменные и ссылки неизменяемы. Изменяемые переменные и ссылки явно создаются с помощью mutключевого слова.

Постоянные элементы в Rust всегда неизменяемы.

// постоянные элементы всегда неизменяемы const ALWAYS_IMMUTABLE : bool = true ;   struct  Object {  х : использовать , y : usize ,}fn  main () {  // явно объявить изменяемую переменную let mut mutable_obj = Object { x : 1 , y : 2 };          mutable_obj . х = 3 ; // Ладно    пусть mutable_ref = & mut mutable_obj ;     mutable_ref . х = 1 ; // Ладно    пусть immutable_ref = & mutable_obj ;    immutable_ref . х = 3 ; // ошибка E0594    // по умолчанию переменные неизменяемы let immutable_obj = Object { x : 4 , y : 5 };         immutable_obj . х = 6 ; // ошибка E0596    let mutable_ref2 = & mut immutable_obj ; // ошибка E0596       пусть immutable_ref2 = & immutable_obj ;    immutable_ref2 . х = 6 ; // ошибка E0594 }    

Scala [ править ]

В Scala любую сущность (узко, привязку) можно определить как изменяемую или неизменяемую: в объявлении можно использовать val(значение) для неизменяемых сущностей и var(переменную) для изменяемых. Обратите внимание, что даже несмотря на то, что неизменяемая привязка не может быть переназначена, она по-прежнему может относиться к изменяемому объекту, и по-прежнему можно вызывать изменяющие методы для этого объекта: привязка неизменна, но базовый объект может быть изменяемым.

Например, следующий фрагмент кода:

значение  maxValue  =  100 var  currentValue  =  1

определяет неизменяемую сущность maxValue(целочисленный тип определяется во время компиляции) и изменяемую сущность с именем currentValue.

По умолчанию классы коллекций, такие как Listи, Mapявляются неизменяемыми, поэтому методы обновления возвращают новый экземпляр, а не изменяют существующий. Хотя это может показаться неэффективным, реализация этих классов и их гарантии неизменности означают, что новый экземпляр может повторно использовать существующие узлы, что, особенно в случае создания копий, очень эффективно. [11] [ нужен лучший источник ]

См. Также [ править ]

  • Clojure
  • Erlang
  • F #
  • Haskell
  • Пролог
  • Tcl
  • Scala
  • Мутаторный метод

Ссылки [ править ]

Эта статья содержит некоторые материалы из книги Perl Design Patterns Book.

  1. ^ «неизменное прилагательное - Определение, изображения, произношение и примечания по использованию - Оксфордский словарь для продвинутых учащихся на OxfordLearnersDictionaries.com» . www.oxfordlearnersictionaries.com .
  2. ^ a b c Goetz et al. Параллелизм Java на практике . Addison Wesley Professional, 2006, раздел 3.4. Неизменность
  3. ^ «6.005 - Разработка программного обеспечения» .
  4. Дэвид О'Мира (апрель 2003 г.). «Изменяемые и неизменяемые объекты: убедитесь, что методы нельзя переопределить» . Ранчо Ява . Проверено 14 мая 2012 . Предпочтительный способ - сделать класс финальным. Иногда это называют «строгой неизменяемостью». Это не позволяет кому-либо расширять ваш класс и случайно или намеренно сделать его изменяемым.
  5. ^ «Встроенные функции - документация Python v3.0» . docs.python.org .
  6. ^ a b D Спецификация языка § 18
  7. ^ D Спецификация языка § 12.16 (Термины массив и срез используются как синонимы.)
  8. ^ «Как создать неизменяемый класс и объект в Java - учебный пример» . Javarevisited.blogspot.co.uk. 2013-03-04 . Проверено 14 апреля 2014 .
  9. ^ "Неизменяемые объекты" . javapractices.com . Проверено 15 ноября 2012 года .
  10. ^ «Неизменяемость в JavaScript: противоположная точка зрения» . Desalasworks .
  11. ^ «Scala 2.8 Collections API - Конкретные неизменяемые классы коллекций» . Scala-lang.org . Проверено 14 апреля 2014 .

Внешние ссылки [ править ]

  • Неизменяемые объекты в C # за 3 простых шага.
  • Статья Теория и практика Java: видоизменять или не изменять? по Брайан Гетц , от IBM DeveloperWorks - Сохраненная копия в Интернет Архиве по Брайан Гетц , от IBM DeveloperWorks - Сохраненная копия в Интернет Архиве
  • Неизменяемые объекты из JavaPractices.com
  • Неизменяемые объекты из Портлендского репозитория паттернов
  • Immutable.js от Facebook
  • Неизменяемые структуры в проекте C # с открытым исходным кодом в Codeplex
  • Неизменяемые коллекции в официальной библиотеке .NET от Microsoft
  • Неизменяемые объекты в C # от Tutlane.com