2016-11-06 51 views
1

對於使用Java一段時間之後,對於Scala來說我相當新,所以如果這是一個基本問題,我很抱歉。我有一種方法,我希望以浮點或雙精度運行,看起來用Scala的多態性很容易。在Java中,我發現要做到這一點的唯一方法是重載方法,並讓一個接受浮點型參數,另一個接受雙重參數,但我希望多態性能夠讓我避免這種情況,並且只有一種方法可以工作與任一。我到目前爲止已經實現了它的方式看起來像這樣(https://stackoverflow.com/a/4033390/6247850對於如何使通用操作參數之間工作):多態方法中的Scala類型轉換

def Sample[A: Numeric](x: A, y: A)(implicit num: Numeric[A]): A= { 
    import num._ 
    var out = 2.0.asInstanceOf[A] * x * y 
    return out 
} 

這工作得很好,對於雙精度,但導致ClassCastException - 如果我嘗試運行它在浮動。我可以通過將其更改爲2.0.toFloat.asInstanceOf[A]來硬編碼解決方法,這使我認爲必須有某種方式來執行此操作,但像這樣的硬編碼使得它變得通用。我還必須做一些看起來不成比例的工作,通過使用這個答案https://stackoverflow.com/a/34977463/6247850來使部門正常工作,並且構建起來以便比較工作。

本質上,我想要的是能夠指定方法應該運行和返回的精度。問題來自將方法中使用的其他變量轉換爲適當的類型,因爲.asInstanceOf[A]不起作用,除非它已經是正確的類型。

回答

3

下面是使用從Numeric明確方法簡短的解決方案:

def Sample[A: Numeric](x: A, y: A)(implicit num: Numeric[A]): A = { 
    num.times(
    num.fromInt(2), 
    num.times(x, y) 
) 
} 

這使得先解決與重載算術運算符任何含糊之處。這裏的實際密鑰是fromInt方法的使用,所以我們可以把它寫短(就像在你的代碼)與運營商再次:

def Sample[A: Numeric](x: A, y: A)(implicit num: Numeric[A]): A = { 
    import num._ 
    fromInt(2) * x * y 
} 

你不需要這裏的任何鑄造(在這個特殊的例子) 。下面是一個使用演示:

scala> Sample(2.5D, 0.01D) 
res12: Double = 0.05 

scala> Sample(2.5F, 0.01F) 
res13: Float = 0.049999997 

至於更一般的情況時,只是有一些數字,而不是2,你不知道你希望它是提前的,我想,你不能用它解決哪種類型只是一個多態函數。您可以定義一個類型類別併爲您希望使用的特定類型提供隱式實例(ad-hoc polymorphism)。

+0

哇,謝謝你的快速回復!一次使用很多操作時,有什麼辦法可以使它更簡潔?類似'num.times(2),num.times(x,num.plus(num.fromInt(1),y)))'的代碼與'2 * x *(1 + y)' – user6247850

+0

@ user6247850其實是的,只是在你原來的代碼中。我會添加這個選擇。另請參閱關於一般情況的更新。 – laughedelic