Как имитировать аргументы ключевого слова в функциях ActionScript 3

Функции в Python можно вызывать с помощью аргументов ключевого слова в форме ключевое слово = значение. Например, следующая функция:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"

можно вызвать любым из следующих способов:

parrot(1000)
    parrot(action = 'VOOOOOM', voltage = 1000000)
    parrot('a thousand', state = 'pushing up the daisies')
    parrot('a million', 'bereft of life', 'jump')

В ActionScript 3 такой возможности нет. Как мне лучше всего подражать этому?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
0
1 684
4

Ответы 4

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

Очень интересно. Вы должны добавить к своему ответу фрагмент кода с сайта.

Soviut 04.01.2009 03:57

Но это всего лишь массив параметров. Это не дает вам именованных параметров и не позволяет изменять порядок параметров, исключать параметры и т. д.

bzlm 17.02.2009 20:02

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

public function awesomefunction(input:Object):void {
    if (input.foo) trace("got foo");
    if (input.bar) trace("got bar");
}

А затем при вызове этого действия:

awesomefunction( { foo : 23, bar : 99 } );

Скобки {} создают встроенный объект. Длинную версию приведенного выше кода можно записать так:

var obj:Object = new Object();
obj.foo = 23;
obj.bar = 99;
awesomefunction( obj );

Если вместо этого вы дадите ему массив:

awesomefunction( [23, 99 ] );

([] - это сокращение для массива кстати)

Индексы будут доступны следующим образом:

public function awesomefunction(input:Object):void {
    if (input[0]) trace("got foo");
    if (input[1]) trace("got bar");
}

Итак, чтобы объединить все это, вы можете использовать тот факт, что || Оператор возвращает значение объекта, которое сначала оценивается как истинное, а не только правда:

public function awesomefunction(input:Object):void {
    var foo:int = input.foo || input[0];
    var bar:int = input.bar || input[1];
    if (foo) trace("got foo:", foo);
    if (bar) trace("got bar:", bar);
}

Итак, приведенная выше функция даст одинаковый результат для всех этих трех вызовов:

awesomefunction( { foo : 23, bar :55 } );
awesomefunction( { bar : 55, foo : 23 } );
awesomefunction( [ 23, 55 ] );

Однако это не позволит вам смешивать именованные и пронумерованные, но вы можете сделать так:

awesomefunction( { foo : 23, 1 : 55 } );

Это не очень красиво, но работает!

В ActionScript 3.0 есть специальный тип, называемый ...(отдых). Поместите этот тип в список параметров функции, и тогда эта функция сможет принимать любое количество аргументов. Правильный sytanx: ... имя_массива, где arrayName - имя массива, который будет содержать аргументы.

public function forYou( ...args ) : void{
   for(var i : int = 0; i 

Но это всего лишь массив параметров. Это не дает вам именованных параметров и не позволяет изменять порядок параметров, исключать параметры и т. д.

bzlm 17.02.2009 20:01

Короткий ответ заключается в том, что в ActionScript порядок параметров является частью сигнатуры функции. Чтобы обойти этот факт, вам придется либо делать дополнительную работу, либо заниматься плохими методами кодирования, которые вас укусят позже. Я бы сказал, что у вас есть два «хороших» варианта получения гибкости, аналогичной той, которую вы ищете. Формальный способ - определить класс данных, который будет действовать как параметр функции. Это:

public class ComplaintData {
    public var state:String = "a stiff";
    public var action:String = "voom";
    public var type:String = "Norwegian Blue";
    public var voltage:String;

    public function ComplaintData( v:String ) {
        voltage = v;
    }
}

// somewhere else....

function parrot( cd:ComplaintData ) {
    trace "-- This parrot wouldn't " + cd.action;
    // etc.
}

var cd:ComplaintData = new ComplaintData( "a million" );
cd.action = "jump";
parrot( cd );

Если ситуация является более специальной, менее формальным подходом является либеральное использование необязательных параметров и разрешение вызывающей стороне передавать null для любого незавершенного параметра, который они хотят опустить. Это дает вам гибкость, но вы жертвуете изрядной чистотой:

function parrot( voltage:String, 
                 state:String=null, 
                 action:String=null, 
                 type:String=null)  {
    if (state==null) { state = 'a stiff'; }
    if (action==null) { action = 'voom'; }
    if (type==null) { type = 'Norwegian Blue'; }
    // ....
}
parrot('1000')
parrot('1000000', null, 'jump')

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

Самый сбалансированный способ работы с грамматикой - просто использовать по возможности необязательные параметры, например:

function parrot( voltage:String, 
                 state:String='a stiff', 
                 action:String='voom', 
                 type:String='Norwegian Blue')  {
    // ...
}
parrot('1000');
parrot('1000000', 'pushing up the daisies');
parrot('a million', 'bereft of life', 'jump')

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

+1 к использованию типизированного объекта или просто работе с ним. Использование ... или анонимного объекта только усложнит поддержку вашей кодовой базы.

Richard Szalay 08.01.2009 12:17

Другие вопросы по теме