2010-02-03 32 views
2

我有一個類似於C#String.Format方法的「格式」方法,它具有以下簽名:將可選參數(... rest)傳遞給在AS3中接受可選參數的另一個方法

在一類命名的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}」, 「你好」, 「世界」)返回預期字符串 「你好,世界」。現在,我試圖讓我的日誌類使用這種方法,但我無法通過可選變量傳遞。在日誌類的方法的簽名是:

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

如果我通過「休息」直接進入StringTools.format(原始,休息),它在通過作爲一個數組,而不是作爲一個系列的參數,所以如果我將它稱爲l​​iks this: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初始化爲[null,raw],然後再次獲得「Hello World,6,數字爲{1}」。

我做錯了什麼?將可選參數從一個需要可選參數的方法傳遞給另一個需要可選參數的方法的正確方法是什麼?

謝謝!

回答

1

我認爲你在正確的線上使用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); 
} 

編輯:您需要將「空」作爲應用第一個參數,因爲第一個參數是什麼被認爲是「這個」當函數被調用。由於函數是靜態的(並且在任何情況下都不依賴'this'),所以您可以傳遞null,但是您必須通過

0

其實,剛發現這是我的問題。只要參數數組中的第一個元素爲null,它應該使用所描述的參數集合方法正常工作。我不確定爲什麼null是必要的,但它可以很好地工作。

+0

如果將callFunction更改爲StringTools.format而不是StringTools.format.call,則不需要「null」。 http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Function.html#call%28%29 – sberry 2010-02-03 18:23:05

1

你也可以做這樣的事情(當然這不是字符串格式化最好的實現):

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轉移到其他數組上,而不是建立一個新的var更容易。

相關問題