返回

浅析深浅拷贝:手把手带你掌握实现技巧

前端

在编程中,我们经常需要复制对象,这时就涉及到深拷贝和浅拷贝的概念。两者之间存在着微妙的差异,理解这些差异对于高效管理数据至关重要。本文将深入探讨深拷贝和浅拷贝,并提供手写实现的详细指南。

深拷贝与浅拷贝

浅拷贝 只复制对象的引用,而不是创建新对象。这意味着对副本的任何更改都会影响原始对象,反之亦然。浅拷贝适用于不需要修改原始对象的情况下。

深拷贝 会创建一个新对象,并复制原始对象的所有属性值。对副本的任何更改都不会影响原始对象,因为它们是独立的实体。深拷贝适用于需要创建原始对象独立副本的情况。

手写实现

JavaScript

// 浅拷贝
const shallowCopy = (obj) => {
  return {...obj};
};

// 深拷贝
const deepCopy = (obj) => {
  if (typeof obj !== "object" || obj === null) {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  }

  const newObj = {};
  for (const key in obj) {
    newObj[key] = deepCopy(obj[key]);
  }

  return newObj;
};

Python

# 浅拷贝
from copy import copy

def shallow_copy(obj):
  return copy(obj)

# 深拷贝
import copy

def deep_copy(obj):
  if isinstance(obj, (list, tuple, set, dict)):
    return copy.deepcopy(obj)
  return obj

C++

// 浅拷贝
T* shallow_copy(const T* obj) {
  return new T(*obj);
}

// 深拷贝
T* deep_copy(const T* obj) {
  T* new_obj = new T;
  *new_obj = *obj;
  return new_obj;
}

Java

// 浅拷贝
public static <T> T shallowCopy(T obj) {
  try {
    return (T) obj.clone();
  } catch (CloneNotSupportedException e) {
    throw new RuntimeException(e);
  }
}

// 深拷贝
import java.io.*;

public static <T> T deepCopy(T obj) {
  try {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(obj);

    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    return (T) ois.readObject();
  } catch (IOException | ClassNotFoundException e) {
    throw new RuntimeException(e);
  }
}

总结

深拷贝和浅拷贝是对象复制的两种不同方式,了解它们之间的差异至关重要。通过手写实现,我们可以深入理解这些概念并根据需要灵活地使用它们。本文提供了 JavaScript、Python、C++ 和 Java 中深拷贝和浅拷贝的详细实现,为开发者提供了实践这些技术所需的知识和工具。