ActionScript - 传递休息类型强制失败?

时间:2010-11-08 15:43:26

标签: actionscript-3 rest parameter-passing

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

我只是传递然后将Shape对象作为rest参数进行修复。当对象到达最终函数时,它们跟踪为[对象形状],但是在下一行我收到类型强制失败,说明它无法转换为Shape。

输出:

[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 个答案:

答案 0 :(得分:1)

乍一看这有点反直觉,但它确实有意义......

声明rest参数时,实际传递的参数将在运行时包装在Array中。

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

myFunction(1,2,3);

您的函数将收到一个包含3个值的数组。

这正是这里发生的事情:

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

ìtems本身就是passer正文中的一个数组。但是当你调用receiver时,这个包含2个形状的数组被包装在另一个数组中,因为你声明receiver采用了一个rest参数。

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)让receiver“解包”其余参数以获取内部数组。基本上是循环items[0]而不是items

2)将您的功能签名更改为:

private function receiver(items:Array):void

3)更改调用receiver的方式,以便将数组作为参数列表传递:

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

这样做的效果相当于:

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

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

如果您确实需要passer来取休息参数,可以使用选项3)。否则,我会选择选项2)。选项1)是我最不喜欢的,因为它是最脆弱的,但它也是一个有效的选项。