代码之家  ›  专栏  ›  技术社区  ›  Rhys Causey

将可选参数(…rest)传递给另一个在AS3中接受可选参数的方法

  •  2
  • Rhys Causey  · 技术社区  · 15 年前

    我有一个“格式”方法,其工作方式与C string.format方法类似,具有以下签名:

    在名为StringTools的类中:

    /**
     * Formats a string, based on C# String.Format method.
     * @param raw A string with numbered tokens, such as "{0}, {1}"
     * @param rest Values that replace the numbered tokens in raw.
     */
    public static function format(raw:String, ...rest:*):String;
    

    stringtools.format(“0,1,”,“hello”,“world”)按预期返回字符串“hello,world”。现在,我正试图让我的日志类使用这个方法,但是我在传递可选变量时遇到了困难。日志类中方法的签名为:

    public static function infof(raw:String, ...rest:*):String;
    

    如果我将“rest”直接传递给stringtools.format(raw,rest),它将作为数组而不是作为一系列参数传入,因此如果我这样称呼它:infof(“0,1”,“hello”,“world”),我会得到字符串“hello,world,1”,因为它将第一个标记替换为整个值数组。

    我还尝试构造一个参数数组,并调用如下方法:

    var collectArgs:Array = [raw];
    
    for (var i:Number = 0; i < rest.length; i++)
    {
    collectArgs.push(rest[i]);
    }
    
    var callFunction:Function = StringTools.format.call;
    
    trace(callFunction.apply(null, collectArgs));
    

    然而,这追踪到“世界,6”。所以,看起来参数被移动了。所以,我尝试将collectargs初始化为[空,原始],得到“HelloWorld,6”。这个数字又是1”。

    我做错什么了吗?将可选参数从一个期望可选参数的方法传递到另一个期望可选参数的方法的正确方法是什么?

    谢谢!

    3 回复  |  直到 15 年前
        1
  •  1
  •   stephen    15 年前

    我觉得你用Apply是对的。这似乎说明了你想要的行为:

    static function f1(raw:String, ...rest:*):void
    {
        trace("f1: "+raw+" "+rest);
        rest.unshift(raw);
        f2.apply(null, rest); 
    }
    
    static function f2(raw:String, ...rest:*):void
    {
        trace("f2: "+raw+" "+rest);
    }
    
    function passSomeArguments():void
    {
        f1("A",1,2,3);
    }
    

    编辑:需要将“null”作为要应用的第一个参数传递,因为调用函数时,第一个参数被视为“this”。因为函数是静态的(在任何情况下都不依赖于“this”),所以可以传递空值,但必须传递 某物 .

        2
  •  1
  •   sberry    15 年前

    您也可以这样做(当然,这不是字符串格式的最佳实现):

    public static function format(raw:String, ...rest:*):String {
        if (rest[0] is Array && rest.length == 1) {
            rest = rest[0];
        }
        var r:RegExp = /(\{\d+\})/g;
        var matches:Array = raw.match(r);
        for (var i:Number = 0; i < rest.length; i++) {
            raw = raw.replace(matches[i], rest[i]);
        }
        return raw;
    }
    

    然后,您的infof函数将如下所示:

    public static function infof(raw:String, ...rest:*):void {
        var formatted = StringTools.format(raw, rest);
    }
    

    正如我的注释中所提到的,如果从callFunction setter的末尾移除call方法,那么不需要将null作为第一个参数提供。见 http://livedocs.adobe.com/ 了解调用方法的实际作用,以及第一个参数的作用。

    正如@stephen所提到的,将原始var卸载到rest数组中要比构建新的var简单得多。

        3
  •  0
  •   Rhys Causey    15 年前

    实际上,只是发现这是我的问题。只要arguments数组中的第一个元素为空,就可以使用所描述的参数集合方法。我不知道为什么需要空值,但是这样可以很好地工作。