ActionScript - Принудительная передача типа отдыха не удалась? - PullRequest
1 голос
/ 08 ноября 2010

Я понятия не имею, почему следующий код не работает.

Я просто передаю, а затем переправляю объекты Shape в качестве параметра rest. когда объекты достигают конечной функции, они отслеживаются как [форма объекта], но затем на следующей строке я получаю ошибку приведения типа, утверждая, что она не может быть преобразована в форму.

Выход:

[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 Ответ

1 голос
/ 09 ноября 2010

Это немного противоречит на первый взгляд, но на самом деле это имеет смысл ...

Когда вы объявляете параметр rest, аргументы, которые вы фактически передаете, оборачиваются в Array во время выполнения.

Это означает, что если вы выполните:

myFunction(1,2,3);

Ваша функция получит массив с 3 значениями.

Это именно то, что здесь происходит:

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

ìtems сам по себе является массивом в теле passer.Но когда вы вызываете receiver, этот массив, содержащий 2 фигуры, переносится в другой массив, потому что вы объявили, что receiver принял параметр rest.

Когда ваш цикл в receiver пытается преобразовать каждый элементв Shape, он терпит неудачу (потому что вы не можете преобразовать 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) Измените способ вызова приемника, чтобы массив передавался каксписок аргументов:

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

Эффект был бы эквивалентен выполнению этого:

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

За исключением случаев, конечно, он обрабатывает список элементов динамически.

Если вам действительно нужно passer, чтобы получить параметр отдыха, вы можете выбрать вариант 3).В противном случае я бы выбрал вариант 2).Вариант 1) мне нравится меньше всего, так как он самый хрупкий, но он также допустим.

...