2012-06-22 21 views
6

讓我有一個名爲MathUtil的實用程序類。Scala帶常量0的數字init

它看起來像這樣。

abstract class MathUtil(T:Numeric){ 
    def nextNumber(value:T) 
    def result():T 
} 

讓我繼承它這樣

class SumUtil[T:Numeric] extends MathUtil[T]{ 
    private var sum:T = 0 
    override def nextNumber(value:T){ 
    sum = sum + value 
    } 
    override def result():T = sum 
} 

我用下面的語句有問題現在

private var sum:T = 0 

,我必須初始化總和爲0。我猜的任何數字有一種方法來表示0. Im對於Scala很新穎。我該如何解決這個問題?

+0

謝謝大家的答案。我有一個後續問題。可以說我有一個具有MathUtils類型的可重寫成員的類。 – questionersam

回答

11

Numeric type class instancezero方法你想要做什麼:

class SumUtil[T: Numeric] extends MathUtil[T] { 
    private var sum: T = implicitly[Numeric[T]].zero 
    override def nextNumber(value: T) { 
    sum = implicitly[Numeric[T]].plus(sum, value) 
    } 
    override def result(): T = sum 
} 

請注意,您還需要實例爲plus方法,除非你導入Numeric.Implicits._,在這種情況下,你可以使用+。您也可以通過不使用在這種情況下勢必語法上下文清潔碼了一點:

class SumUtil[T](implicit ev: Numeric[T]) extends MathUtil[T] { 
    import Numeric.Implicits._ 
    private var sum: T = ev.zero 
    override def nextNumber(value: T) { 
    sum = sum + value 
    } 
    override def result(): T = sum 
} 

這是完全等價的:上下文綁定版本是本次隱含參數只是語法糖,但如果你需要明確使用這個參數(就像你在這裏做的那樣,它的zero),我發現編寫desugared版本更清晰。

+0

嘿特拉維斯!很高興見到你在這裏張貼(這是來自奧斯汀的本)。不幸的是,這個數字的東西,國際海事組織,只是非常難看。事實證明它也很慢。國際海事組織整個斯卡拉隱含機制是笨重,脆弱和難以理解,你仍然需要像@specialized其他垃圾,這也是主要黑客入侵。我認爲使用C++風格的類專業化可以更好地表達這些東西,它們只會*工作*所有人都期望的方式,本質上是通過使用s/int/double /或其他方法來複制實現。 –

+0

@UrbanVagabond:嗨,本!我同意'Numeric'是一團糟,我不記得我最後一次在自己的代碼中使用它,但我個人認爲問題在於Scala實現類型類的方式(我實際上已經增長了喜歡)。 –

0

我認爲需要澄清一下你想要完成的工作。從Scala文檔中,數字類型本身是通用的。我的感覺是你真正想要的是描述一個MathUtil抽象,它處理任何數字[T]而不是數字[_]的子類,這是你的代碼當前描述的。這是基於這個假設的正確實施。

//Define a MathUtil that works on any T 
abstract class MathUtil[T] { 
    def nextNumber(value: T) 
    def result(): T 
} 

//Define a SumUtil that works on any T that has an available Numeric 
//Will search implicit scope, but also allows you to provide an 
//implementation if desired. 
class SumUtil[T](implicit n: Numeric[T]) extends MathUtil[T] { 
    //Use the Numeric to generate the zero correctly. 
    private var sum: T = n.zero 
    //Use the Numeric to correctly add the sum and value 
    override def nextNumber(value: T) = sum = n.plus(sum, value) 
    override def result(): T = sum 
} 

//Test that it works. 
val a = new SumUtil[Int] 
val b = List(1,2,3) 

b map a.nextNumber //Quick and dirty test... returns a meaningless list 
println(a.result) //Does indeed print 6 

如果上述內容不符合您的要求,請澄清您的問題。

+0

你是不對的......'[T:Numeric]'是一個上下文綁定,並且會擴展到'[T](隱含的n:數字[T])',所以你的代碼幾乎和OP的相同爲'n.zero'。 – drexin