Функции в 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 такой возможности нет. Как мне лучше всего подражать этому?





Вы можете реализовать нечто подобное, используя переменное количество аргументов для функции, показанной здесь.
Но это всего лишь массив параметров. Это не дает вам именованных параметров и не позволяет изменять порядок параметров, исключать параметры и т. д.
Если вы что-то напутаете, во время компиляции не возникнет никаких ошибок, но вы можете сделать что-то вроде этого:
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 Но это всего лишь массив параметров. Это не дает вам именованных параметров и не позволяет изменять порядок параметров, исключать параметры и т. д.
Короткий ответ заключается в том, что в 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 к использованию типизированного объекта или просто работе с ним. Использование ... или анонимного объекта только усложнит поддержку вашей кодовой базы.
Очень интересно. Вы должны добавить к своему ответу фрагмент кода с сайта.