Незмінні об'єкти та незмінні колекції
Одним з найтонших моментів дебатів щодо змінних та незмінних об'єктів є можливість поширення концепції незмінності на колекції. Незмінний об'єкт - це об'єкт, який часто представляє єдину логічну структуру даних (наприклад, незмінний рядок). Якщо у вас є посилання на незмінний об'єкт, вміст об'єкта не зміниться.
Незмінна колекція - це колекція, яка ніколи не змінюється.
Коли я виконую операцію над колекцією, що змінюється, я змінюю колекцію на місці, і всі об'єкти, які мають посилання на колекцію, побачать зміни.
Коли я виконую операцію над незмінною колекцією, посилання повертається на нову колекцію, що відображає зміни. Усі об'єкти, які мають посилання на попередні версії колекції, зміни не побачать.
Розумним реалізаціям не обов’язково потрібно копіювати (клонувати) всю колекцію, щоб забезпечити цю незмінність. Найпростішим прикладом є стек, реалізований у вигляді окремо пов'язаного списку та операцій push / pop. Ви можете повторно використовувати всі вузли з попередньої колекції в новій колекції, додавши лише один вузол для натискання та не клонувавши вузлів для поп-файлу. Операція push_tail в окремо пов'язаному списку, з іншого боку, не така проста чи ефективна.
Незмінні проти змінних змінних / посилань
Деякі функціональні мови приймають поняття незмінності для об'єктних посилань, дозволяючи лише одне призначення посилань.
- У Erlang це справедливо для всіх "змінних". Я можу призначити об'єкти посилання лише один раз. Якби я працював над колекцією, я не зміг би перенести нову колекцію до старої посилання (назва змінної).
- Scala також вбудовує це у мову, де всі посилання декларуються за допомогою var або val , при цьому вали мають лише одне призначення та підтримують функціональний стиль, але vars дозволяють створювати більше C-подібну або Java-подібну структуру програми.
- Декларація var / val необхідна, тоді як у багатьох традиційних мовах використовуються необов'язкові модифікатори, такі як final у java та const у C.
Простота розробки проти продуктивності
Практично завжди причиною використання незмінного об'єкта є сприяння вільному програмуванню побічних ефектів та простому міркуванню про код (особливо в умовах дуже одночасного / паралельного середовища). Вам не потрібно турбуватися про те, що основні дані будуть змінені іншим об'єктом, якщо об'єкт є незмінним.
Основний недолік - продуктивність. Ось запис простий тест, який я зробив на Java, порівнюючи деякі непорушні та незмінні предмети в іграшці.
Питання щодо продуктивності є суперечливими в багатьох додатках, але не у всіх, саме тому багато великих числових пакетів, таких як клас Numpy Array в Python, дозволяють проводити оновлення великих масивів на місці. Це було б важливо для областей застосування, які використовують великі матричні та векторні операції. Ці великі паралельні дані та обчислювально обчислювальні проблеми досягають значного прискорення, працюючи на місці.
string
є незмінним, принаймні в .NET, і я думаю, що і в багатьох інших сучасних мовах.