2017-08-28 72 views
3

Haxe允許拋出幾乎任何東西,但其捕獲能力似乎有點有限。例如,我有拋出一個錯誤類型枚舉值的靜態誤差函數:捕捉拋出的枚舉值

class Error 
{ 
    public static var CATCH_ALL:Bool = false; 
    public static function Throw(aError:ErrorType, ?ignore:Bool=false, ?inf:PosInfos):Void 
    { 
     trace('Error: $aError at ' + inf.className + ':' + inf.methodName + ':' + inf.lineNumber); 
     if (!CATCH_ALL && !ignore) 
     { 
      throw aError; 
     } 
    } 
} 

enum ErrorType 
{ 
    NULL_PARAM(msg:String); 
    NOT_FOUND(msg:String); 
} 

雖然我能趕上幾乎任何東西,我僅限於基本類型,類類型和枚舉類型。這意味着我可以捕獲每個字符串,但不是專門包含「土豆」的字符串,例如。如果我創建了多個錯誤類,我可以在忽略其他類的情況下捕獲特定的類類型,但同樣的事情對於枚舉來說似乎是不可能的。會有以下代碼可以替代編譯嗎?

選擇的 catch
try 
{ 
    Error.Throw(ErrorType.NULL_PARAM('Potato')); 
} 
catch (e:ErrorType.NULL_PARAM) trace(e); //does not work nor compile 
catch (e:ErrorType) trace(e); //works, but catches every error 

回答

2

-expressions是limited to types /不提供模式匹配功能,如switch作用:

Catch塊是從頂部檢查底部與第一個,其類型是兼容拋出的價值被挑選出來。

所有ErrorType枚舉是與ErrorType兼容。這意味着不幸的是,我認爲你能做的最好的方法就是趕上ErrorType,然後在catch-block內部進行選擇,使用switch並可能重新投擲它。但是請注意,簡單的throw e目前會導致堆棧跟蹤丟失,如#4159中所述。

+0

感謝您的回答。所以如果我重新拋出一個錯誤,我會失去堆棧跟蹤。我可以在錯誤對象中包含PosInfos,至少在沒有堆棧的情況下保留位置數據。或者簡單地回到我的舊方式,即爲每種類型的錯誤提供一個錯誤對象和擴展類。由於我在某處讀取帶參數的枚舉值與代碼生成中的類相似,我希望他們可以充當獨特的類型。 –

+1

請注意,您可以保留某些平臺上的調用堆棧 - 例如在Neko上有['neko.Lib.rethrow'](http://api.haxe.org/neko/Lib.html#rethrow),就像那個問題中提到的那樣。 – Gama11