你期望不可变列表的不变性有多深?

如果你有一个不可变列表,那么你希望它总是在你要求的时候返回对同一个对象的引用

list.get(0) 

我的问题是,您是否希望能够改变对象并在下次从列表中获取突变时反映出变异?

这取决于具体情况。 在通用库中,我们应该假设列表是不可变的。 对列表中元素的更改将反映给所有调用者,这是每次返回相同引用的直接结果。

但是,如果这是一个专门的不可变树(或其他), 并且记录如此,那么你会希望列表中的项本身是不可变的,这就成了一个没有实际意义的问题。

问题,如果不是关于列表的不变性,而是关于所包含对象的不变性。

实际上,如果您有引用类型,则列表中的不可变实体是引用。 这意味着引用将始终相同。 现在引用的对象是否只发生变化取决于它是什么类型的对象。 如果对象是不可变的(例如,.NET和Java中的字符串,或.NET中的所有值类型),则对象不能更改。

否则,对象可以更改,并且对同一对象的所有其他引用将看到更改的状态,因为它们包含对同一实例的引用。 因此,正如我在开头所写的那样,这完全独立于列表(以及它是否是不可变的)。

这通常是预料之中的。 该列表是不可变的,这意味着您无法在其中添加或删除项目或完全替换项目。 如果您希望这些项目是不可变的,您必须自己处理。 列表肯定无法阻止您在引用对象时改变对象的状态。

是。

当我得到它们时,我不希望不可变列表克隆它的对象,除非它被记录为这样做。

这实际上取决于你提出这个问题的背景。 任何有经验的Java或C#开发人员都知道技术上几乎不可能拥有一般的“深层不变性”,因此不会期望这样。 在C ++中,这是一个非常复杂的主题 ,因此大多数开发人员可能也不期望可靠的深层不变性。 另一方面,D编程语言确实具有传递不变性的语言级概念 ,因此D程序员可能会在任何有意义的地方(通常是这样)预期它。

假设一家维修店想要保留所有曾经访问过的汽车的永久附加记录,这样每辆车进入车主时都可以知道它是否曾经在车间。 哪个更好:

  1. 保留每辆车的VIN(车辆识别号码)的永久记录
  2. 制作每辆车的副本(因为VIN必须是唯一的,必须具有与原件不同的VIN)并永久存储重复的车辆。

请注意,汽车本身是一个可变对象,但由VIN表示的汽车标识是不可变的。 完全可能的是,一辆汽车在参观商店时是蓝色的,因此被漆成了红色。 因此,即使有人能够轻松找到任何带有VIN的汽车,汽车列表(VIN)以及他们在车间的时间也不允许人们确定上周四有多少辆蓝色汽车在维修。 另一方面,如果列表的目的是让人知道先前车辆是否已进入车间,则VIN列表正是人们所需要的。 如果不是拥有VIN,而是拥有重复车辆的集合,那么创建和存储所有这些重复车辆的成本不仅远远大于存储VIN的成本,而且该集合对于所述的VIN来说几乎是无用的。目的(确定某辆车之前是否曾访问过)。

是的,知道Java,对于一个“不可变的” List我不希望T是不可变的,除非T是不可变的。 但是,例如List的合理实现是每次复制Date 。 问题是Date是可变的,可以与其他相等的Date区分开来。