如何在ActionScript 3中创建一个数组的浅拷贝

4
var a:Array = ["a","b","c"];

var b:Array;

/* insert code here to copy 'a' and assign it to 'b'*/

你很幸运:浅拷贝是微不足道的,深拷贝需要大量代码,因为数组不是类型化集合 :-) - Adam Smith
3个回答

12

摘自As3参考指南:

Array类没有内置的复制数组的方法。您可以通过调用不带参数的concat()或slice()方法来创建一个浅拷贝。在浅拷贝中,如果原始数组具有对象元素,则仅复制对对象的引用而不是对象本身。副本指向与原始数组相同的对象。对对象所做的任何更改都会反映在两个数组中。

如果在concat和slice之间选择,由于性能方面的优势,应该选择Concat。

在此处阅读更多关于此主题的信息:http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7ee7.html

为了澄清:

    private function shallowCopy():void{
        var a:Array = ["h", "e", "l", "l", "o"];
        var b:Array = a.concat(); 

        trace("Shallow copy:");
        trace("Before delete: " + a);
        trace("Before delete: " + b);
        delete a[0];
        trace("After delete: " + a);
        trace("After delete: " + b);            
    }

我总是忘记AS3是Javascript的超集。谢谢。 - Gareth Davis
1
你的 deepCopy() 函数并没有进行深拷贝,它只是复制了数组本身的引用(即根本没有进行数组拷贝)。在 AS3 中,深拷贝需要循环遍历数组内容,并手动构造与之匹配类型的新对象,然后将其值复制过去。var b:Array = a; 只是创建了一个指向你的数组 a 的新引用。 - Adam Smith
那我一定误解了这个概念。我会删除代码 :) 谢谢你指出来! - rzetterberg
深拷贝是指数组中引用的任何对象都会被克隆,克隆体将在新数组中对应的位置上被引用。因为对象通常会引用其他对象,所以你可以看到这可能是固定深度或完全递归的。但这比递归地克隆所有东西更棘手,因为你的数组中可能有两个对象(A和B)都引用C。当你进行深拷贝时,Aclone和Bclone应该引用相同的Cclone,而不是C的两个新克隆体。这就是为什么我告诉Gareth他问了一个简单的问题的原因 :-) - Adam Smith
你可以在这里找到深拷贝的实现:[http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7ee7.html] - BlueRaja - Danny Pflughoeft

8
该行代码如下:
var b:Array = a.concat();

0
如果数组仅包含字符串或数字值,则只需进行“浅层”复制,如Adam和rzetterberg所述。
如果数组包含其他数组、对象/类实例等,则如果您需要其中所有对象也是唯一的而不仅仅是引用,则应进行深层复制。您可以通过以下方式实现:
var ba:ByteArray = new ByteArray(); 
ba.writeObject(a); // Copy the original array (a) into a ByteArray instance
ba.position = 0; // Put the cursor at the beginning of the ByteArray to read it
var b:Array = ba.readObject(); // Store a copy of the array in the destination array (b)
ba.clear(); // Free memory

这对于复制没有任何concat或splice方法的对象也非常有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接