Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Общий вопрос про повторные определения (http://www.flasher.ru/forum/showthread.php?t=203872)

am_devcorp 10.10.2013 23:16

Общий вопрос про повторные определения
 
Вот допустим, есть у нас код.
Код AS3:

switch (dir) {
                case TOP:
                    var i:int = 0
                    for (var j:int = 0; j < pics[0].length; j++) {
                        что-то делаем с pics[i][j]
                    }
                    break;
 
                case RIGHT:
                    var j:int = pics[0].length - 1
                    for (var i:int = 0; i < pics.length; i++) {
                        что-то делаем с pics[i][j]
                    }
 
                    break;
                case BOT:
                    var i:int = pics.length - 1
                    for (var j:int = 0; j < pics[0].length; j++) {
                        что-то делаем с pics[i][j]
                    }
                    break;
                case LEFT:
                    var j:int = 0
                    for (var i:int = 0; i < pics.length; i++) {
                        что-то делаем с pics[i][j]
                    }
                    break;
                default:
            }

т.е. мы в зависимости от dir по разному проходим по матрице.
Вообще подробности не важны, может мы несколько раз по разному проходимся по матрице, не суть, главное, что подряд идут несколько похожих по смыслу циклов с i и опционально j. В таком случае компилятор сыпет в консоль ворнинги duplicate variable definition. Но щит, Шерлок, это я и сам вижу, но как лучше от них избавляться?

Вариант 1) Забить, но это несолидно, когда проект собирается не молча.
Вариант 2) В начале объявить эти злосчастные i и j и убрать объявления. Но может это мои тараканы мне это тоже не нравится, ибо это вроде как повторное использование переменной в другом месте, что не есть хорошо.

Есть ли какие-нибудь еще кроме (2) практики исправления таких ситуаций?

Akopalipsis 10.10.2013 23:22

Только один вариант - обьявить i перед заходом в switch
Можно i=0 вообще убрать из цикла, но так будет не красиво.
Немного я упустил Ваш код)) ещё j добавить и делать в таком же духе.

Добавлено через 2 минуты
Код AS3:

var i:int;
var j:int;
switch (dir) {
                case TOP:
                    for (i=0; i < pics[0].length; j++) {
                        что-то делаем с pics[i][j]
                    }
                    break;
 
                case RIGHT:
                    for (i=0; i < pics.length; i++) {
                        что-то делаем с pics[i][j]
                    }
 
                    break;
                case BOT:
                    for (i=0; i < pics[0].length; j++) {
                        что-то делаем с pics[i][j]
                    }
                    break;
                case LEFT:
                    for (i=0; i < pics.length; i++) {
                        что-то делаем с pics[i][j]
                    }
                    break;
                default:
            }


Bletraut 10.10.2013 23:25

Объявить в самом начали, а потом уже присваивать им значения?

Babylon 10.10.2013 23:25

правильнее всё таки писать var в цикле.

Добавлено через 33 секунды
Bletraut, да дурдом

Akopalipsis 10.10.2013 23:36

Цитата:

Bletraut, да дурдом
А почему инициализация вне цикла - дурдом?

Babylon 10.10.2013 23:38

Какой в ней смысл? переменная, что где-то перед циклом используется?

КорДум 10.10.2013 23:45

Ну и, если на то пошло, обращение к геттеру length происходит каждый виток цикла, кэшируйте значение. Конструкция вида "i < pics[0].length" плоха еще тем, что нулевой элемент берется тоже каждую итерацию. Кэшировать нужно и это.

Akopalipsis 10.10.2013 23:45

Цитата:

Какой в ней смысл? переменная, что где-то перед циклом используется?
я конечно не могу спорить, но мне кажется, что переменная вне цикла, это как приватная переменная для класса...
Так ведь работает..
Код AS3:

var i:int;
for (i = 0; i < 10; i++)
{
        trace(i);
}
for (i = 0; i < 10; i++)
{
        trace(i);
}


КорДум 10.10.2013 23:47

Все локальные переменные метода находятся в одном скоупе, вне зависимости, где они они были объявлены. Если это не переменные вложенной функции, она не расширяет родительский скоуп, но содержит его в себе. Компилятор все равно все переменные, где бы они не объявлялись, затолкает в хидер метода, плюс уберет повторное определение, если таковое имеется, и ругнется ворнингом.

expl 11.10.2013 00:36

Цитата:

Вариант 1) Забить, но это несолидно, когда проект собирается не молча.
Вынести объявления вверх как общие и смириться
Если смириться тяжело - в опциях mxmlc есть галочка - не выдавать ворнинги про дублирование переменных (проверять порядок объявления и область видимости, правда, компилятор не будет что так, что так - просто флудить не будет)
Насколько опасно отключать? Ну случалось, внутри блока объявлял переменную, думая что её нет снаружи и узнавал это из ворнинга.
С другой стороны отключать/не отключать - это мёртвому припарки. Когда у тебя половину переменных надо искать на полэкрана выше и не понятно где ты их собирался использовать, а где - нет, и когда компилятор даже не проверяет, объявлена ли переменная до её использования.

Сильный аргумент _не_ отключать: не пугать людей, которые так или иначе будут компилировать ваш код - по умолчанию то предупреждения включены
Цитата:

Вариант 2) В начале объявить эти злосчастные i и j и убрать объявления. Но может это мои тараканы мне это тоже не нравится, ибо это вроде как повторное использование переменной в другом месте, что не есть хорошо.
Вы правы, это отвратительно, и такое поведение в стандарт ECMA вписал какой-то негодяй :)
Но есть хорошая новость: во многих других языках область видимости переменных ограничена блоком, а не методом (Java, C#, haXe, F#, Ocaml, C++)

Aquahawk 11.10.2013 13:03

Цитата:

Сообщение от Babylon (Сообщение 1148308)
правильнее всё таки писать var в цикле.

Добавлено через 33 секунды
Bletraut, да дурдом

В других языках да, но не в семействе ECMAScript 262. Подробнее читайте стандарт или http://habrahabr.ru/post/127482/

caseyryan 11.10.2013 14:19

Зачем заморачиваться и писать где-то вначале?
Я вообще на этот счет не парюсь, и делаю так:
Код AS3:

for (var i :int = 0; i < 10; i++) {
 
}
for (i = 0; i < 15; i++) {
 
}
// и т.д.


Akopalipsis 11.10.2013 14:22

Цитата:

Зачем заморачиваться и писать где-то вначале?
А если так сделать в первом блоке свитч, а по условию будет второй, то по сути будет переменная без инициализации или нет?

caseyryan 11.10.2013 14:25

Нет, не будет. Компилятор ее сам вынесет в начало метода. Здесь лишь вопрос удобства для программиста.

Aquahawk 11.10.2013 15:01

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

Код AS3:

i = 0

В этом случае перед началом цикла в переменную будет присвоен 0.


Вот вам примерчик на разобраться. Несмотря что булеан по умолчанию равен нулю, это умолчание присваивается один раз на этапе инициалицации который происходит разу при определении. И это происходит вверху метода, не смотря на объявление в теле цикла.
Во втором случае = false, как обычное использование, останется на месте.

Код AS3:

var i:int;
 
for (i = 0; i < 5; i++) {
        var b:Boolean;
        trace(b);
        b = true;
}
 
trace('-------');
 
for (i = 0; i < 5; i++) {
        var b2:Boolean = false;
        trace(b2);
        b2 = true;
}


Код:

false
true
true
true
true
-------
false
false
false
false
false


Akopalipsis 11.10.2013 15:18

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

caseyryan 11.10.2013 16:28

Цитата:

что код выше, может еррор выкинуть при компиляции.
В других языках, например в джаве, обязательно выкинет. Но не в ас3.

expl 11.10.2013 16:44

Цитата:

Зачем заморачиваться и писать где-то вначале?
Я вообще на этот счет не парюсь, и делаю так:
Код AS3:

for (var i :int = 0; i < 10; i++) {
 
}
for (i = 0; i < 15; i++) {
 
}
// и т.д.


Такой код просто править не удобно. Удалил 1-й цикл - надо править второй, поменял местами - надо править оба.

caseyryan 12.10.2013 18:58

да, но это не особо напряжно


Часовой пояс GMT +4, время: 08:27.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.