2017-04-21 95 views
1

我用的方法嘗試在斯卡拉這是試圖取決於他們是多麼大的圓號碼,例如如果該值低於1,則將其舍入至少一個小數點是有意義的;而不是保留一個整數。這裏就是我想:取整數值參數類型斯卡拉

def roundSmart[A](num: A)(implicit numeric: Numeric[A]) = num match { 
    case num if num < 1 => numeric.toDouble(num) 
    case _ => numeric.toInt(num) 
    } 

會拋出這個錯誤:

value < is not a member of type parameter A

當然的參數需要接受函數簽名以內的範圍參數類型的,因爲它可能採取整數或雙打,這增加了更多的複雜性。

我已經採取了條件聲明第一情況從這個答案 - Using comparison operators in Scala's pattern matching system並很渴望使用函數式編程方法。也許還有一些內置的scala函數,如Math.round()可能有助於將第二個條件四捨五入,而不是刪除任何小數。謝謝!

+0

'math.round'並在斯卡拉存在 –

回答

1

TL; DR:你需要每一個數字的方法是內部numeric

的錯誤是不言自明的:你的類型A(這是通用的)沒有一個<方法。

但是,你有什麼是與所有數字方法類型類,所以你應該將它們導入:

import numeric._ 

該進口(除其他事項外),隱式轉換OrderingOps,其所需的方法。但是這種比較無法正常工作,因爲1不是A,而是Int

解決方案只需使用fromIntnumeric

雖然我們在這樣做,你會有意想不到的結果輸入,如-234.2e123 ......你最好做你的測試你的號碼的絕對值(abs也是numeric的方法)。

另外,如果你想要做一個簡單的測試,也沒有必要使用模式匹配,一個if else說法是不夠

def roundSmart[A](num: A)(implicit numeric: Numeric[A]) = { 
    import numeric._ 
    if (abs(num) < fromInt(1)) toDouble(num) else toInt(num) 
} 
+0

注意,返回類型將是'雙',你可能也想做一些這方面的事情。 –

+0

感謝您的回覆。所以錯誤會很大 - 但是如果它總是返回一個Double,無論我是否想要一個Integer,那麼它都無法完成我打算做的事情(請閱讀整個問題以瞭解目的)。所以我必須使用錯誤的技術。此外,*模式匹配*是因爲我將有兩個以上的條件。 –

+0

由於您有靜態類型,所以必須有一個定義良好的返回類型。你應該考慮你想要的是什麼,這取決於你的用例。 –