如果你有一个不可变的列表,你希望它在你请求时总是返回对同一个对象的引用,比如
list.get(0)
我的问题是,您是否希望能够对对象进行变异并在下次从列表中获取它时反映该变异?
如果你有一个不可变的列表,你希望它在你请求时总是返回对同一个对象的引用,比如
list.get(0)
我的问题是,您是否希望能够对对象进行变异并在下次从列表中获取它时反映该变异?
这取决于上下文。在通用库中,我们应该假设列表是不可变的。列表中元素的更改将反映给所有调用者,这是每次返回相同引用的直接结果。
但是,如果这是一个专门的不可变树(或其他什么),并且被记录为这样,那么您会期望列表中的项目本身是不可变的,这将成为一个没有实际意义的问题。
问题不是关于列表的不变性,而是关于所包含对象的不变性。
事实上,如果你有引用类型,列表中的不可变实体就是引用。这意味着引用将始终相同。现在被引用的对象是否改变只取决于它是什么类型的对象。如果对象是不可变的(例如,.NET 和 Java 中的字符串,或 .NET 中的所有值类型),则对象不能更改。
否则,对象可以更改,并且对同一对象的所有其他引用将看到更改的状态,因为它们持有对同一实例的引用。因此,正如我在开头所写的,这完全独立于列表(以及它是否不可变)。
这通常是可以预料的。该列表是不可变的,这意味着您不能在其中添加或删除项目或完全替换项目。如果您希望这些项目是不可变的,您必须自己处理。一旦你得到一个对它的引用,这个列表当然不能阻止你改变对象的状态。
是的。
我不希望一个不可变的列表在我获取它们时克隆它的对象,除非它被记录为这样做。
这实际上取决于您提出该问题的上下文。任何有经验的 Java 或 C# 开发人员都知道,在技术上几乎不可能拥有一般的“深度不变性”,因此不会期望这一点。在 C++ 中,这是一个非常复杂的主题,因此大多数开发人员可能也不期望可靠的深度不变性。另一方面,D 编程语言确实具有传递不变性的语言级概念,因此 D 程序员可能会在任何有意义的地方期望它(这很常见)。
假设一家维修店想要保留所有曾经访问过的汽车的永久附加记录,以便当每辆汽车进入时,车主可以查明它以前是否曾在店里。哪个会更好:
请注意,汽车本身是一个可变对象,但身份由 VIN 表示的汽车的属性是不可变的。一辆在参观商店时是蓝色的汽车完全有可能被漆成红色。因此,即使一个人能够根据其 VIN 轻松定位任何汽车,但汽车列表 (VIN) 以及它们何时在店内也无法确定例如上周四维修了多少辆蓝色汽车。另一方面,如果该列表的目的是让人们知道一辆进货车辆以前是否在商店里,那么 VIN 列表正是人们所需要的。如果一个人没有 VIN,而是拥有一组重复的汽车,那么不仅创建和存储所有这些重复汽车的成本会远远高于存储 VIN 的成本,
是的,知道Java,对于“不可变”,List<T>
我不希望 T 是不可变的,除非 T 是不可变的。然而,一个合理的实现,比如说,每次都List<Date>
复制。Date
问题是它Date
是可变的,可以与其他相等Date
的 s 区分开来。