不变性是否意味着每次更改时都会完全重新创建大量集合?

Does immutability mean that huge collections get completely recreated every time they change?

我最近一直在尝试学习函数式编程。具体来说,我对 Clojure 很感兴趣。我理解大多数关于数据不变性的论点,但有一件事对我来说没有意义。假设我有一个非常大的集合,例如地图或包含数亿项的数组。如果我不能改变它,那是否意味着每次我想添加一个新项目时我实际上是在重新创建整个集合?这听起来是个可怕的主意。在一切都是不可变的语言中如何处理这种情况?

对于 Clojure,它们不会每次都重新创建。 Rich Hickey 确保利用 persistent data structures, as he explains in an "Expert to Expert" interview.

你可以把它想象成一个链表。

class LinkedList<E> {
    E data;
    LinkedList<E> next;

    LinkedList<E> cons(E item) {
        return new LinkedList(item, this);
    }
}

每次你cons一个值放到前面时,你不需要创建一个新的链表,而只是保留对前一个的引用。

类似地,即使像地图这样的数据结构也可以共享大量的数据,当它们只有很小的差异时。这有助于减少使用的大小。

此外,Clojure 还提供 transient data structures,它们是其不可变集合的可变版本,允许您对数据结构进行多次更改,而无需花费 copying/sharing 数据。