AS3: лить или "как"?

Есть ли разница в использовании, эффективности или фоновой технике между

var mc:MovieClip = MovieClip(getChildByName("mc"));

и

var mc:MovieClip = getChildByName("mc") as MovieClip;

?

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

Ответы

Ответ 1

В этой статье хорошо описаны различия:

Ключевое различие между литьем и оператором as - это поведение при сбое. Когда сбой в действии ActionScript 2 возвращается null. Когда сбой в действии ActionScript 3, возникает TypeError. С как оператор в ActionScript 3, всякий раз, когда литье вызывает значение по умолчанию для возвращаемого типа данных.

as также позволяет отбрасывать на Array, что было невозможно, поскольку функция преобразования Array() имела приоритет.

РЕДАКТИРОВАТЬ: относительно производительности, используя as, как сообщается, быстрее, чем стиль создания стиля вызова функций в различных статьях: [1 ] [2] [3]. В первой цитированной статье рассматриваются различия в производительности и отчеты о том, что as быстрее на 4x-4,5 раза.

EDIT 2: В нормальном лучшем случае не только as 4x-4,5x быстрее, но когда вы завершаете преобразование стиля (cast) в блок try-catch и ошибку фактически заканчивается тем, что его бросают, это больше похоже на 30x - 230x быстрее. В AS3, если вы думаете, что собираетесь сделать что-то исключительное (в этом он может пропустить ошибку), тогда ясно, что вы всегда должны смотреть перед тем, как прыгать. Никогда не используйте try/catch, если это не связано с API, и это означает, что никогда не будет (cast). Также полезно посмотреть на последствия производительности try/catch, даже если исключение не выбрано. Там есть штраф за выполнение настройки блока try/catch даже в счастливом случае, когда ничего не происходит.

Ответ 2

Так как никто еще не ответил на аспект производительности прямо, и это было в вашем вопросе, as значительно эффективнее и быстрее во время выполнения, чем (cast) в AS3.

http://jacksondunstan.com/articles/830

В сочетании со всеми другими факторами я не вижу абсолютно никакой причины использовать (cast) и считаю, что этого следует избегать полностью.

Отложенный комментарий ниже на самом деле напоминает мне о хорошем моменте в том, что касается этого. Если вы (cast), то вы почти наверняка окажетесь в ситуации, когда вам придется попробовать/поймать

try{
    SubType(foo).bar();
}catch(e:TypeError){
    // Can't cast to SubType
}

Это убийственно медленно. Единственный способ проверить это is сначала

if(foo is SubType){ 
  SubType(foo).bar();
}

Это просто кажется неправильным и расточительным.

Ответ 3

AS3 Кастинг одного типа в другой содержит ответ, который также отвечает на это: ключевое слово "as" присваивает null при неудачном преобразовании, в противном случае оно выбрасывает TypeError.

Ответ 4

Лучше всего использовать ключевое слово as.

as имеет то преимущество, что не бросает RTE (ошибка времени выполнения). Например, скажем, у вас есть класс Dog, который нельзя отнести в MovieClip; этот код выдает RTE:

var dog:Dog = new Dog();
var mc:MovieClip = MovieClip(Dog);

TypeError: Ошибка # 1034: Тип принудительного выполнения не удалось: невозможно преобразовать Dog в MovieClip.

Для того, чтобы сделать этот код "безопасным", вы должны были бы включить листинг в блок try/catch.

С другой стороны, as будет более безопасным, потому что он просто возвращает null, если преобразование завершается с ошибкой, а затем вы можете сами проверить ошибки, не используя блок try/catch:

var dog:Dog = new Dog();
var mc:MovieClip = Dog as MovieClip;
if (mc) 
    //conversion succeeded
else
    //conversion failed

Ответ 5

Предпочитайте использование отливки для использования as operator. Используйте оператор as только в том случае, если принуждение может выйти из строя, и вы хотите, чтобы выражение оценивалось как null, а не выбрасывало исключение.

Сделайте это:

IUIComponent(child).document

Не это:

(child as IUIComponent).document

Соглашения о кодировании

Ответ 6

(cast) и "as" - две совершенно разные вещи. В то время как "как" просто говорит компилятору интерпретировать объект так, как если бы он имел данный тип (который работает только в одном или в подклассах или в числовых/строковых преобразованиях), (cast) пытается использовать функцию статического преобразования целевого класса, Который может сбой (сброс ошибки) или возврат нового экземпляра целевого класса (уже не тот же объект). Это объясняет не только разницу скоростей, но и поведение в событии Error, как описано Alejandro P.S.

Последствия очевидны: 'as' должен использоваться, если класс объекта известен кодеру, но не компилятору (потому что он запутан с помощью интерфейса, который только называет суперкласс или '*'). Проверка "есть" перед или нулевая проверка после (быстрее) рекомендуется, если предполагаемый тип (или тип, совместимый с автоматическим принуждением) не может быть на 100% гарантирован.

(cast) следует использовать, если необходимо фактическое преобразование объекта в другой класс (если возможно вообще).

Ответ 7

Кроме запуска или отсутствия RTE или возврата значения null, существует значительная разница, когда мы управляем ошибками в swf, загружаемом в отдельный домен приложения.

Использование Loader.uncaughtErrorEvents для обработки ошибок загруженного swf; если мы сделаем как "event.error as Error", результирующая ошибка будет иметь исходную трассировку стека (те же, что были пойманы в swf, которые вызвали ошибку), а если они были выбраны с помощью Error (event.error), стек трассировка ошибки будет изменена текущей трассировкой стека (в которой был сделан бросок).

Пример кода:

if (event && event.error && event.error is Error) {
    debug ("Casting with 'as Error'") 
    debugStackTrace (event.error as Error); 
    debug ("casting with 'Error (...)'"); 
    debugStackTrace (Error (event.error)); 
}

Пример вывода:

Casting with 'as Error' 
ReferenceError: Error # 1056 
at Player / onEnterFrame () 
casting with 'Error (...)' 
Error: ReferenceError: Error # 1056 
at package :: HandlerClass / uncaughtErrorHandler () 
at EventInfo / listenerProxy ()

Ответ 8

var mc:MovieClip = MovieClip(getChildByName("mc"));

НАПРАВЛЯЕТ НЕПОСРЕДСТВЕННО УСТАНОВИТЬ КАК moviklip

var mc:MovieClip = getChildByName("mc") as MovieClip;

сделает mc действовать как мувиклип, если требуемый тип тот же