2016-03-14 186 views
3

我想要做這樣的事情創建一個數字:斯卡拉從字符串

def parse[A: Numeric](str: String): A = { 
    if A =:= Int, str.toInt 
    if A =:= Float, str.toFloat 
    if A =:= BigInt, BigInt(str) 
    ... 
    ... 
} 

遺憾的是,似乎沒有在Numeric特質定義fromString。在Scala中實現這一點最常用的方法是什麼?

回答

1

由於類型類的可擴展性,所要求的通常是不可能的;您無法匹配所有可能的Numeric實現,因爲任何用戶定義的類型都可以實現它。同樣因爲這個原因,並不能保證每個Numeric[A]都可以從一個字符串中解析出來。

有兩種解決方法。一個是部分解決方案,你確保只使用表示整數文字的字符串,然後用IntfromString來解析它,然後用NumericfromInt來轉換它。

另一種方式是在函數調用時傳入實際的字符串解析函數。這可能有點像作弊,因爲您的parse方法不再有任何實際的工作,但可以使其對含義非常有用。

最直接的方法是隻添加一個(可能是隱含的)String -> A參數(或者可能爲String -> Option[A]以減少運行時錯誤)。達到此目的的另一種方法是去the typeclass route again and implement something like a Readable typeclass。然後,你可以有你的功能如下所示:

def parse[A: Numeric: Readable](x: String): A = ... 

現在你只需要確保你有Readable[A]實現所有你關心的A有關。

+0

這正是我在這裏所做的(請參閱'Scannable'類類):https://github.com/pathikrit/better-files/blob/master/core/src/main/scala/better/files/Scanner .scala#L79-L86但是我希望Scala的數字特質裏有一個'fromString' ... – pathikrit

+0

其實現在我想到了,我認爲還有更好的方法。讓我寫出編輯.... – badcook

+0

沒關係;我所能想到的一切都只是回到同樣的事情。我唯一能想到的其他事情就是使用'spire'並使用它的'Integral'類型類型,然後匹配它是一個'Fractional'還是一個'Integral',然後使用各自的'fromDouble'或'fromInt'方法(連同'toDouble'和'toInt')來解析它。你的'Scannable'看起來不錯,但我不會稱自己是Scala的專家,並會順從其他人。 – badcook