我剛剛開始使用Scala,而我認爲應該很容易的東西很難弄清楚。我想實現以下功能:如何在Scala中實現一個通用的數學函數
def square(x:Int):Int = { x * x }
這只是正常的,但如果我想嘗試做任何一種數量的此功能工作,我希望能夠做到以下幾點:
def square[T <: Number](x : T):T = { x * x }
這抱怨說:錯誤:值*是不是類型參數T
我需要實現此一特質中的一員?
我剛剛開始使用Scala,而我認爲應該很容易的東西很難弄清楚。我想實現以下功能:如何在Scala中實現一個通用的數學函數
def square(x:Int):Int = { x * x }
這只是正常的,但如果我想嘗試做任何一種數量的此功能工作,我希望能夠做到以下幾點:
def square[T <: Number](x : T):T = { x * x }
這抱怨說:錯誤:值*是不是類型參數T
我需要實現此一特質中的一員?
這是我在堆棧溢出或關於Scala的first questions之一。問題在於Scala保持與Java的兼容性,這意味着它的基本數字類型等同於Java的基元。
問題在於Java基元不是類,因此沒有允許「數字」超類型的類層次結構。
說得透徹一點,Java和,因此,Scala中,並沒有看到一個Double
的+
和一個Int
的+
之間的共同點。
方式斯卡拉終於繞開這個限制得到的是通過使用Numeric
,和它的子類Fractional
和Integral
,在所謂的類型類模式。基本上,你用這樣的:
def square[T](x: T)(implicit num: Numeric[T]): T = {
import num._
x * x
}
或者,如果你不需要任何的數字運算,但你打電話做的方法,你可以使用方面的約束語法類型聲明:
def numberAndSquare[T : Numeric](x: T) = x -> square(x)
欲瞭解更多信息,請參閱我自己的問題的答案。
很好的解釋。我必須爲Typeclass模式谷歌 - 不知道存在。謝謝。 – Collin 2010-10-30 14:35:17
如果你有這個,但是: 'def squareAddOne [T](x:T)(implicit num:Numeric [T]):T = {import num._; x * x + 1}' 如何將Int添加到數字中? – 2016-08-01 15:00:00
哦,我想我的問題是在這裏回答:http://stackoverflow.com/a/2388386/901263 – 2016-08-01 15:03:30
您可以定義square
爲:
def square[T: Numeric](x: T): T = implicitly[Numeric[T]].times(x,x)
這種方法的優勢在於,它將爲具有一個隱式轉換爲數字[T](即整型,浮點型,雙,字符任何類型T的工作, BigInt,...或您爲其提供隱式轉換的任何類型)。
編輯: 不幸的是,如果你嘗試像List(1,2,3).map(square)
(特別是你遇到麻煩,你會得到一個編譯錯誤,如「無法找到數字類型[T]的證據參數內含價值」爲了避免這個問題,你可以重載square
返回一個函數:
object MyMath {
def square[T: Numeric](x: T) = implicitly[Numeric[T]].times(x,x)
def square[T: Numeric]: T => T = square(_)
}
希望有人能夠更好地理解類型inferencer將解釋這是爲什麼
另外,可以撥打如Derek Williams在scala-user mailing list thread中指出的那樣,。
對於後人來說,給這個問題一個更具體的標題可能是有用的,比如「我如何在Scala中實現通用數學函數?」。 – 2010-10-30 17:25:59
同意,謝謝。 – jimmyb 2011-05-05 15:49:05