代码之家  ›  专栏  ›  技术社区  ›  Chunky Chunk

actionscript-传递REST类型强制失败?

  •  1
  • Chunky Chunk  · 技术社区  · 14 年前

    我不知道下面的代码为什么不起作用。

    我只是简单地将形状对象作为一个休息参数传递和重新打包。当对象到达最终函数时,它们跟踪为[对象形状],但在下一行中,我收到类型强制失败,说明无法将其转换为形状。

    输出:

    [object Shape],[object Shape]
    TypeError: Error #1034: Type Coercion failed: cannot convert []@27b68921 to flash.display.Shape.
        at Test/receiver()
        at Test/passer()
        at Test()
    

    代码:

    package
    {   
    import flash.display.Sprite;
    import flash.display.Shape;
    
    public class Test extends Sprite
        {
        public function Test()
            {
            //Create Shapes
            var myFirstShape:Shape = new Shape();
            myFirstShape.graphics.beginFill(0);
            myFirstShape.graphics.drawRoundRect(0, 0, 100, 100, 50);
    
            var mySecondShape:Shape = new Shape();
            mySecondShape.graphics.beginFill(0);
            mySecondShape.graphics.drawRoundRect(0, 0, 100, 100, 50);
    
            //Pass Shapes
            passer(myFirstShape, mySecondShape);
            }
    
        private function passer(...items):void
            {
            //Pass Shapes Again
            receiver(items);
            }
    
        private function receiver(...items):void
            {
            //Rest Trace As [object Shape], [object Shape]
            trace(items);
    
            //Type Coercion Failed ??!!
            for each    (var element:Shape in items)
                        {
                        trace(element);
                        }
            }
        }
    }
    
    1 回复  |  直到 14 年前
        1
  •  1
  •   Juan Pablo Califano    14 年前

    乍一看,这有点违反直觉,但实际上是有道理的…

    声明REST参数时,实际传递的参数在运行时包装在数组中。

    这意味着,如果你这样做:

    myFunction(1,2,3);
    

    您的函数将收到一个具有3个值的数组。

    这正是发生在这里的事情:

    private function passer(...items):void
        {
        //Pass Shapes Again
        receiver(items);
        }
    

    ìtems 它本身就是 passer . 但是当你打电话的时候 receiver ,包含两个形状的数组被包装在另一个数组中,因为您声明 接受者 获取了一个休息参数。

    当你的循环 接受者 尝试将每个项转换为形状,但失败(因为无法转换 Array 变成一个 Shape )

    你可以看到这个改变了你的代码:

    private function receiver(...items):void
        {
        //Rest Trace As [object Shape], [object Shape]
        trace(items);
        trace(items.length);// --> traces 1
        trace(items[0].length);// --> traces 2; this is the Array you want.
    
    }
    

    所以,根据您真正想要实现的目标,您有几个选项可以解决这个问题。

    1)有 接受者 “展开”其余参数以获取内部数组。基本循环彻底 items[0] 而不是 items .

    2)将函数签名更改为:

    private function receiver(items:Array):void
    

    3)更改调用接收器的方式,使数组作为参数列表传递:

        private function passer(...items):void
        {
        //Pass Shapes Again
        receiver.apply(this,items);
        }
    

    这样做的效果相当于:

    receiver(items[0],items[1]);
    

    当然,除了动态处理项目列表。

    如果你真的需要 过路人 要获取一个rest参数,可以使用选项3)。否则,我会选择选项2)。选项1)是我最不喜欢的,因为它是最脆弱的,但它也是一个有效的选项。