Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 as3:如何按值复制对象_Actionscript 3_Flex3 - Fatal编程技术网

Actionscript 3 as3:如何按值复制对象

Actionscript 3 as3:如何按值复制对象,actionscript-3,flex3,Actionscript 3,Flex3,我需要在每个其他对象中有一个公共对象的实例,我有。我正在修改我拥有的每个子对象中该对象的值 比如说。我有一张瓷砖地图,还有一个机器人按特定顺序在上面移动。每个机器人都在将他已经访问过的瓷砖标记为visited=true。但总的来说,我不想改变主地图 我试图树立一个榜样: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="

我需要在每个其他对象中有一个公共对象的实例,我有。我正在修改我拥有的每个子对象中该对象的值

比如说。我有一张瓷砖地图,还有一个机器人按特定顺序在上面移动。每个机器人都在将他已经访问过的瓷砖标记为visited=true。但总的来说,我不想改变主地图

我试图树立一个榜样:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" 
    applicationComplete="complete()">
    <mx:Script>
        <![CDATA[
            private var array:Array = new Array( 1, 2, 3, 4);
            public function complete():void
            {
                trace("here " + array);
                var a:Array = array;
                a[0] = 100;
                trace("here " + array);
            }
        ]]>
    </mx:Script>
</mx:Application>

有人能帮助我理解如何复制数组(例如,按值复制,而不是按引用复制)吗

编辑: 可能包含一些语法错误

public class MyObject
{
    private var arr:Array;
    private var bool:Boolean;

    // ...

    public function clone ():MyObject
    {
        var obj:MyObject = new MyObject();

        // clone values
        obj.arr = this.arr.slice();
        obj.bool = this.bool;

        return obj;
    }
}

对于克隆阵列,您可以使用


以下是poke所述方法的替代方法:

首先,我想谈一谈波克的帖子


  • “为该特定对象定义自己的克隆函数。没有任何特殊函数可自动为任何任意对象定义克隆函数。”False。ActionScript有一种内置的序列化方法,称为AMF(ActionScript消息格式)。AMF可用于执行非基本体对象的复制

  • “使用自定义克隆方法有很大的优势,即您可以准确地决定要复制什么以及如何复制…”这正是您序列化对象时所做的,因此自定义克隆方法与序列化方法相比没有什么大的优势

  • “…并且返回类型正确(即,您不需要强制转换)。”您也不需要强制转换序列化对象。但是序列化还有一个额外的好处,那就是它是泛型的,使得复制功能是动态的,而不限于特定的类型

  • “[实现一个接口](如果克隆返回一个特殊类型的对象,这将是非常不合适的)”必须定义一个返回类型会使进程处于静态状态,从而锁定您使用特定类型。如果我们使用该语言的动态属性,我们可以使该语言成为一个通用的克隆方法,而不关心类型。这没有什么不合适的

  • “如果将序列化对象取消序列化两次,则获得对象的副本,这只是序列化的附加效果。”通过调用slice()或concat()而不带任何参数来获得数组副本的事实只是这些方法的副作用。我真的不明白你的意思。此外,连载的核心是复制。序列化和反序列化的行为是复制的行为。你不会以某种方式得到完全相同的内存,引用和所有完整的

  • 我有一个问题:在克隆方法中如何处理嵌套的非基本类型

    在你的问题中,你会说“有人能帮我理解如何复制数组,例如,通过值(而不是通过引用)”我认为,在复制对象时,了解浅拷贝和深拷贝之间的区别很重要

    浅拷贝

    这里提供的解决方案(Array.slice()和Array.concat())称为浅拷贝。您得到的是数组的副本。如果数组的内容是基元类型(那些通过值传递而不是通过引用传递的类型),那么您有两个唯一的对象:原始对象和副本。但是,如果您认为数组包含通过引用传递的对象,则数组的原始和副本将具有完全相同的内容。如果对原始阵列中的对象进行更改,这些更改将反映在复制的阵列中。虽然有时这可能是你想要的,但并不总是如此

    深拷贝

    深度复制将遍历要复制的对象的层次结构,并复制它找到的任何对象。然后,将允许您对复制的对象进行任何更改,而不会在原始对象中反映任何更改

    如果要按照poke的建议定义自定义克隆方法,那么复制非优先类型将变得过于复杂。您必须遍历对象的属性,并对任何非基元类型调用自定义clone()方法。但是,如果遇到内置的非基本类型(如数组或字典),则必须重新创建该对象,循环其内容,然后重新开始,检查它是否为非基本类型,如果有,则调用其clone()方法,或者处理数组和字典。它变得过于复杂。总之,这种方法有两个问题:您必须自己处理数组和字典(以及任何内置的非原语类型);您必须对嵌套对象专门调用clone方法(并且知道它们已定义clone方法)

    另一种方法是使用AMF对对象进行序列化,然后再进行反序列化,从而获得深度副本。这直接适用于数组、字典和任何依赖公共属性的非原语

    var t:Array = [];
    t[0] = [1, 2, 3];
    t[1] = new Dictionary();
    t[1]['hello'] = 'world';
    t[2] = {'my': 'object'}
    trace(t, t[1]['hello'], t[2]['my']); // [trace] 1,2,3,[object Dictionary],[object Object] world object
    var t2:Array = clone(t);
    trace(t2, t2[1]['hello'], t2[2]['my']); // [trace] 1,2,3,[object Dictionary],[object Object] world object
    t[0] = [4, 5, 6];
    t[1]['hello'] = 'earth';
    t[2]['my'] = 'other object';
    trace('modified values');  // [trace] modified values
    trace(t, t[1]['hello'], t[2]['my']);  // [trace] 4,5,6,[object Dictionary],[object Object] earth other object
    trace(t2, t2[1]['hello'], t2[2]['my']);  // [trace] 1,2,3,[object Dictionary],[object Object] world object
    
    function clone(source:*):* {
        var b:ByteArray = new ByteArray();
        b.writeObject(source);
        b.position = 0;
        return(b.readObject());
    }
    
    这涵盖了自定义克隆方法的第一个问题和上面的第1点。如您所见,所有对象及其内容都是使用内置方法复制的

    我在这里展示了如何创建clone方法的实现,但是您可以在:mx.utils.ObjectUtil中找到一个

    如果您想深度复制一个私有存储其数据的对象,那么必须实现IExternalizable接口。这将迫使您实现两种方法:

    public function writeExternal(output:IDataOutput):void
    public function readExternal(input:IDataInput):void
    
    在这些函数中,您将私有变量写入输出对象,然后将它们从输入读取到私有变量。然后,当您调用clone时,您将获得对象的完整副本。记住对所有嵌套对象执行此操作

    下面是一个包含两个类的简单实现示例:

    package {
    
        import flash.utils.IExternalizable;
        import flash.utils.IDataInput;
        import flash.utils.IDataOutput;
        import flash.net.registerClassAlias;
    
        public class Car implements IExternalizable {
    
        private var type:String;
            private var contents:Array;
    
            public function Car() {
                registerClassAlias("Car", Car);
            }
    
        public function setVars(type:String, contents:Array):void {
                this.type = type;
                this.contents = contents;
            }
    
        public function setType(type:String):void {
                this.type = type;
            }
    
    
            public function writeExternal(output:IDataOutput):void {
                output.writeUTF(type);
                output.writeObject(contents);
            }
    
        public function readExternal(input:IDataInput):void {
                type = input.readUTF();
                contents = input.readObject();
        }
    
            public function toString():String {
                return "[Car type = " + type + ", contents = " + contents + "]";
        }
    
        }
    
    }
    
    以及:

    要测试它们:

    package {
    
        import flash.display.Sprite;
        import flash.utils.ByteArray;
        import flash.utils.Dictionary;
    
        public class Serial extends Sprite {
    
        public function Serial() {
    
                var person0:Person = new Person();
                person0.setVars("John", "Doe");
                var person1:Person = new Person();
                person1.setVars("Jane", "Doe");
                var car0:Car = new Car();
                car0.setVars("Ford", [person0, person1]);
    
                var person2:Person = new Person();
                person2.setVars("Joe", "Bloggs");
                var car1:Car = new Car();
                car1.setVars("Vauxhall", [person2]);
    
                var street:Array = [car0, car1];
                trace("street = " + street); // [trace] street = [Car type = Ford, contents = [Person firstName = John, secondName = Doe],[Person firstName = Jane, secondName = Doe]],[Car type = Vauxhall, contents = [Person firstName = Joe, secondName = Bloggs]]
    
                var street2:Array = clone(street);
                trace("street2 = " + street2); // [trace] street2 = [Car type = Ford, contents = [Person firstName = John, secondName = Doe],[Person firstName = Jane, secondName = Doe]],[Car type = Vauxhall, contents = [Person firstName = Joe, secondName = Bloggs]]
    
                person0.setVars("Max", "Headroom");
                person1.setVars("Simon", "Le Bon");
                car0.setType("Mini");
    
                person2.setVars("Harry", "Wotsit");
                car1.setType("Austin");
    
            trace("modified values of street"); // [trace] modified values of street
                trace("street = " + street); // [trace] street = [Car type = Mini, contents = [Person firstName = Max, secondName = Headroom],[Person firstName = Simon, secondName = Le Bon]],[Car type = Austin, contents = [Person firstName = Harry, secondName = Wotsit]]
                trace("street2 = " + street2); // [trace] street2 = [Car type = Ford, contents = [Person firstName = John, secondName = Doe],[Person firstName = Jane, secondName = Doe]],[Car type = Vauxhall, contents = [Person firstName = Joe, secondName = Bloggs]]
    
            }
    
            private function clone(source:*):* {
                var b:ByteArray = new ByteArray();
                b.writeObject(source);
                b.position = 0;
                return(b.readObject());
        }
    
        }
    
    }
    
    这涵盖了自定义克隆方法的第二个问题。正如您所看到的,我们不必担心调用任何克隆方法,这一切都是为我们准备的

    我不是说它不完全没有缺点,但它
    package {
    
        import flash.utils.IExternalizable;
        import flash.utils.IDataInput;
        import flash.utils.IDataOutput;
        import flash.net.registerClassAlias;
    
        public class Car implements IExternalizable {
    
        private var type:String;
            private var contents:Array;
    
            public function Car() {
                registerClassAlias("Car", Car);
            }
    
        public function setVars(type:String, contents:Array):void {
                this.type = type;
                this.contents = contents;
            }
    
        public function setType(type:String):void {
                this.type = type;
            }
    
    
            public function writeExternal(output:IDataOutput):void {
                output.writeUTF(type);
                output.writeObject(contents);
            }
    
        public function readExternal(input:IDataInput):void {
                type = input.readUTF();
                contents = input.readObject();
        }
    
            public function toString():String {
                return "[Car type = " + type + ", contents = " + contents + "]";
        }
    
        }
    
    }
    
    package {
    
        import flash.utils.IExternalizable;
        import flash.utils.IDataInput;
        import flash.utils.IDataOutput;
        import flash.net.registerClassAlias;
    
        public class Person implements IExternalizable {
    
        private var firstName:String;
            private var secondName:String;
    
            public function Person() {
                registerClassAlias("Person", Person);
            }
    
        public function setVars(firstName:String, secondName:String):void {
                this.firstName = firstName;
                this.secondName = secondName;
            }
    
            public function writeExternal(output:IDataOutput):void {
                output.writeUTF(firstName);
                output.writeUTF(secondName);
            }
    
        public function readExternal(input:IDataInput):void {
                firstName = input.readUTF();
                secondName = input.readUTF();
            }
    
            public function toString():String {
                return "[Person firstName = " + firstName + ", secondName = " + secondName + "]";
            }
    
        }
    
    }
    
    package {
    
        import flash.display.Sprite;
        import flash.utils.ByteArray;
        import flash.utils.Dictionary;
    
        public class Serial extends Sprite {
    
        public function Serial() {
    
                var person0:Person = new Person();
                person0.setVars("John", "Doe");
                var person1:Person = new Person();
                person1.setVars("Jane", "Doe");
                var car0:Car = new Car();
                car0.setVars("Ford", [person0, person1]);
    
                var person2:Person = new Person();
                person2.setVars("Joe", "Bloggs");
                var car1:Car = new Car();
                car1.setVars("Vauxhall", [person2]);
    
                var street:Array = [car0, car1];
                trace("street = " + street); // [trace] street = [Car type = Ford, contents = [Person firstName = John, secondName = Doe],[Person firstName = Jane, secondName = Doe]],[Car type = Vauxhall, contents = [Person firstName = Joe, secondName = Bloggs]]
    
                var street2:Array = clone(street);
                trace("street2 = " + street2); // [trace] street2 = [Car type = Ford, contents = [Person firstName = John, secondName = Doe],[Person firstName = Jane, secondName = Doe]],[Car type = Vauxhall, contents = [Person firstName = Joe, secondName = Bloggs]]
    
                person0.setVars("Max", "Headroom");
                person1.setVars("Simon", "Le Bon");
                car0.setType("Mini");
    
                person2.setVars("Harry", "Wotsit");
                car1.setType("Austin");
    
            trace("modified values of street"); // [trace] modified values of street
                trace("street = " + street); // [trace] street = [Car type = Mini, contents = [Person firstName = Max, secondName = Headroom],[Person firstName = Simon, secondName = Le Bon]],[Car type = Austin, contents = [Person firstName = Harry, secondName = Wotsit]]
                trace("street2 = " + street2); // [trace] street2 = [Car type = Ford, contents = [Person firstName = John, secondName = Doe],[Person firstName = Jane, secondName = Doe]],[Car type = Vauxhall, contents = [Person firstName = Joe, secondName = Bloggs]]
    
            }
    
            private function clone(source:*):* {
                var b:ByteArray = new ByteArray();
                b.writeObject(source);
                b.position = 0;
                return(b.readObject());
        }
    
        }
    
    }