Путаница в области видимости переменной цикла - PullRequest
12 голосов
/ 18 декабря 2010

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

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.

Ответы [ 3 ]

14 голосов
/ 18 декабря 2010

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

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

    return i;
}

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

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

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. Вы можете получить некоторые трудные для отслеживания ошибки, если вы этого не делаете.

6 голосов
/ 18 декабря 2010

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

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

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

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

3 голосов
/ 18 декабря 2010

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

var i : uint;
for (i=0; i<19; i++) SomeFunction(i);
for (i=0; i<26; i++) SomeOtherFunction(i);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...