我想要做這樣的事情創建一個數字:斯卡拉從字符串
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中實現這一點最常用的方法是什麼?
我想要做這樣的事情創建一個數字:斯卡拉從字符串
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中實現這一點最常用的方法是什麼?
由於類型類的可擴展性,所要求的通常是不可能的;您無法匹配所有可能的Numeric
實現,因爲任何用戶定義的類型都可以實現它。同樣因爲這個原因,並不能保證每個Numeric[A]
都可以從一個字符串中解析出來。
有兩種解決方法。一個是部分解決方案,你確保只使用表示整數文字的字符串,然後用Int
的fromString
來解析它,然後用Numeric
的fromInt
來轉換它。
另一種方式是在函數調用時傳入實際的字符串解析函數。這可能有點像作弊,因爲您的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
有關。
這正是我在這裏所做的(請參閱'Scannable'類類):https://github.com/pathikrit/better-files/blob/master/core/src/main/scala/better/files/Scanner .scala#L79-L86但是我希望Scala的數字特質裏有一個'fromString' ... – pathikrit
其實現在我想到了,我認爲還有更好的方法。讓我寫出編輯.... – badcook
沒關係;我所能想到的一切都只是回到同樣的事情。我唯一能想到的其他事情就是使用'spire'並使用它的'Integral'類型類型,然後匹配它是一個'Fractional'還是一個'Integral',然後使用各自的'fromDouble'或'fromInt'方法(連同'toDouble'和'toInt')來解析它。你的'Scannable'看起來不錯,但我不會稱自己是Scala的專家,並會順從其他人。 – badcook