7

Python中的函数可以使用keyword = value形式的关键字参数调用。例如,以下函数:

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 没有此功能。我将如何最好地模仿它?

4

4 回答 4

7

如果你搞砸了,它不会在编译时抛出任何错误,但你可以这样做:

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 ] );

( [] 是数组 btw 的简写)

索引将可以这样访问:

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

因此,要将所有内容结合在一起,您可以使用 || 运算符返回首先评估为 true 的对象的值,而不仅仅是true

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 } );

它不是很漂亮,但它有效!

于 2009-01-03T23:47:31.620 回答
4

简短的回答是,在 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')

您仍然必须接受只能省略尾随参数的事实,但这就是语言的制作方式(以及其本机方法的定义和使用方式)。

于 2009-01-06T04:47:19.377 回答
1

actionscript 3.0 中有一种特殊类型,称为...(rest)。将此类型放入函数的参数列表中,然后该函数可以接受任意数量的参数。正确的 sytanx 是:...arrayName,其中arrayName是将保存参数的数组的名称。

公共函数 forYou( ...args ) : void{
   for(var i : int = 0; 我
于 2009-01-04T01:04:55.647 回答
0

您可以对此处显示的函数使用可变数量的参数来实现类似的功能。

于 2009-01-03T23:26:02.757 回答