Подтвердить что ты не робот

Смещение пула переменных для цикла

Я заметил странное поведение переменных для циклов. Это не проблема, но меня это очень беспокоит. На самом деле я создал две петли следующим образом:

for (var i:uint; i<19; i++) SomeFunction (i);
for (var i:uint; i<26; i++) SomeOtherFunction (i);

То, что я получил, было предупреждением о компиляции:
Warning: Duplicate variable definition.

Это предупреждение действительно удивило меня. Ничего подобного со мной никогда не случалось на других языках. Кажется, что переменная i попадает в область, которая выше в иерархии и становится доступной из цикла. Я также попытался охватить блок цикла в фигурной скобке, но ничего не изменил.
Почему это происходит? Это нормально? Можно ли это избежать? На данный момент я просто установил разные имена для обеих переменных, но это не настоящее решение, я думаю. Я бы очень хотел использовать переменную i с именем в большинстве моих for-loops.

4b9b3361

Ответ 1

да, переменная приращения цикла находится в области родительских циклов, а не внутри самого цикла. Это преднамеренно, например:

public function getPositionOfValue ( value:String ) : int
{
    for ( var i:int = 0; i < someArray; i++ )
    {
        if (someArray[i] == value )
        {
            break;
        }
    }

    return i;
}

это позволяет вам получить доступ к значению я после завершения цикла. Есть много случаев, когда это очень полезно.

Что вы должны делать в случаях, когда у вас есть несколько циклов внутри одной и той же области, это var я за пределами циклов:

public function getPositionOfValue ( value:String ) : int
{
    var i:int;

    for ( i = 0; i < 15; i++ )
    {
        //do something
    }

    for ( i = 0; i < 29; i++ )
    {
        //do something else
    }

    return i;
}

тогда вы избавитесь от своего предупреждения. Другая вещь, которую следует учесть, - это назвать ваши инкрементные переменные цикла более описательными.

Обновление: две другие вещи, которые следует учитывать:

1) вы не должны использовать uints, кроме таких вещей, как цвета и места, где Flex ожидает uint. Они медленнее, чем int. Источник] 1 Обновление: похоже, что это может быть больше не в более новых версиях флеш-плеера: источник

2), когда вы изменяете переменную приращения цикла внутри декларации цикла, вы хотите убедиться, что вы установите ее на правильное значение инициализации, обычно 0. Вы можете немного успеть отследить ошибки, если вы этого не сделаете.

Ответ 2

Как упоминалось здесь, as3 имеет глобальную и локальную область действия и что об этом.

Он не выполняет масштабирование на уровне блока (или для уровня). При подъеме вы можете даже записать переменные, прежде чем их определить. Это бит, который мог бы сделать мою голову в: -)

В ранних версиях Visual C была эта ошибка, которая привела к разным видам прекрасных фанковых макросов, но это не ошибка в as3, она работает как сконструированная. Вы можете либо ограничить свой код наличием объявления только в первом for, либо переместить объявление вне всех операторов for.

В любом случае, вопрос о том, что язык работает в одном направлении, хотя вы можете подумать, что это плохо: -)

Ответ 3

Объявите переменную i вне циклов, чтобы избежать этого. Пока вы reset его (i = 0), вы все равно можете использовать его во всех циклах.

var i : uint;
for (i=0; i<19; i++) SomeFunction(i);
for (i=0; i<26; i++) SomeOtherFunction(i);