深拷贝带有对象数组属性的对象 - 如何实现或者有其他解决方案?
深拷贝带有对象数组属性的对象 - 如何实现或者有其他解决方案?
这将是一个难以解释的问题。
我有一个相当复杂的Tree类,我尝试简化一下:
class Tree { /** * @var Node[] */ private $nodes; /** * @var Edge[] */ private $edges; } class Node { /** * @var Value[] */ private $values; /** * @var array */ private $someArray; } class Value { /** * @var float */ private $result; }
所以你可以看到我有一个包含两个对象数组(Node和Edge)的Tree对象,每个Node都有一个对象数组(Value),还有一些其他的简单数组,每个Value都有一个result属性。
为了计算result属性,我基本上需要在我的树中上下运行等等...所以有些业务逻辑最终会在仍然是相同的Tree中生成一些计算出的节点结果。
到目前为止,我所做的是这样的:
$tree = myCalculationFunction($tree, $calcParameter); return $tree->getNode(1)->getValue(1)->getResult();
但是当我使用不同的calcParameter调用同样的函数时,我的Tree操作的是引用的Nodes、Values等。
所以我不能这样做:
$initialTree = myCalculationFunction($tree, $calcParameter); $treeOne = myCalculationFunction($initialTree, $calcParameterOne); $treeTwo = myCalculationFunction($initialTree, $calcParameterTwo); $result1 = $treeOne->getNode(1)->getValue(1)->getResult(); $result2 = $treeTwo->getNode(1)->getValue(1)->getResult();
所以我没有$initialTree的深拷贝,因为其中的所有对象都是按引用的。我不能克隆,也不知道如何对这种情况进行手动/自定义的深拷贝,类似于这里(链接)的方法。
我应该如何在这里实现?我基本上需要initialTree保持稳定,每个计算函数调用都操作最初“计算出的树”的完全副本。
问题出现的原因是需要对包含数组属性的对象进行深拷贝。原始的拷贝方法只能进行浅拷贝,即只拷贝对象的引用而不是对象本身。为了解决这个问题,可以通过实现自定义的__clone
方法来进行深拷贝。
具体的解决方法如下:
1. 在Tree
和Node
类中实现__clone
方法。
2. 在__clone
方法中,使用array_map
函数对数组属性进行遍历并进行深拷贝。
3. 根据需要,对其他属性进行类似的处理。
以上是对Node
类的__clone
方法的示例代码:
public function __clone() { $this->values = array_map(function ($value) { return clone $value; }, $this->values); $this->someArray = array_map(function ($elem) { return clone $elem; }, $this->someArray); // clone other properties as necessary }
按照这种模式,对每个类进行类似的处理,可以递归地进行整个树的深拷贝操作。
另外,还可以使用第三方库DeepCopy
来实现深拷贝。这个库遵循了上述方法的原理,但是需要在项目中增加依赖。
通过实现__clone
方法,可以对包含数组属性的对象进行深拷贝。另外,还可以使用第三方库DeepCopy
来简化这个过程。