深度复制和浅复制的区别是什么?


当前回答

深拷贝

深度复制复制所有字段,并复制由字段指向的动态分配的内存。当对象与其引用的对象一起复制时,就会发生深度复制。

浅拷贝

浅复制是对象的逐位复制。创建一个新对象,该对象具有原始对象中值的精确副本。如果对象的任何字段是对其他对象的引用,则只复制引用地址,即只复制内存地址。

其他回答

尤其是iOS开发者:

如果B是a的浅拷贝,那么对于原语数据,它就像B = [a assign];对于对象,B = [A retain];

B和A指向同一个内存位置

如果B是a的深层副本,则B = [a copy];

B和A指向不同的内存位置

B的内存地址与A的相同

B和A的含量相同

广度vs深度;从引用树的角度考虑,将对象作为根节点。

浅:

变量A和B指的是不同的内存区域,当B被分配给A时,这两个变量指的是相同的内存区域。后来对其中一个内容的修改立即反映在另一个的内容中,因为它们共享内容。

深:

变量A和B指的是不同的内存区域,当B被分配给A时,A所指向的内存区域中的值被复制到B所指向的内存区域。后来对其中一项内容的修改仍为A或B所独有;内容不共享。

var source = { firstName="Jane", lastname="Jones" };
var shallow = ShallowCopyOf(source);
var deep = DeepCopyOf(source);
source.lastName = "Smith";
WriteLine(source.lastName); // prints Smith
WriteLine(shallow.lastName); // prints Smith
WriteLine(deep.lastName); // prints Jones

为了避免混淆浅复制和简单地为list分配一个新变量名,再添加一点。

“假设我们有:

x = [
    [1,2,3],
    [4,5,6],
    ]

这个语句创建了3个列表:2个内部列表和一个外部列表。然后,外部列表的引用在名称x下可用

y = x

没有数据被复制。我们在内存的某个地方仍然有相同的3个列表。所有这一切所做的是使外部列表在名称y下可用,除了它之前的名称x

y = list(x)

or

y = x[:]

这将创建一个与x内容相同的新列表。列表x包含对两个内部列表的引用,因此新列表也将包含对这两个内部列表的引用。只复制了一个列表——外层列表。 现在内存中有4个列表,两个内部列表,一个外部列表,以及外部列表的副本。原始外部列表的名称为x,新的外部列表的名称为y。

内部列表没有被复制!此时,您可以从x或y访问和编辑内部列表!

如果你有一个二维(或更高)的列表,或者任何类型的嵌套数据结构,并且你想对所有内容进行完整复制,那么你想在复制模块中使用deepcopy()函数。你的解决方案也适用于2-D列表,迭代外部列表中的项目,并对每个项目进行复制,然后为所有内部副本构建一个新的外部列表。”

来源:https://www.reddit.com/r/learnpython/comments/1afldr/why_is_copying_a_list_so_damn_difficult_in_python/

简单来说,浅拷贝类似于按引用调用,深拷贝类似于按值调用

在引用调用中,函数的形式参数和实际参数都指向相同的内存位置和值。

在按值调用中,函数的形式形参和实际形参都是指不同的内存位置,但具有相同的值。