如何在Scala中实现一个通用的数学函数
我刚刚开始使用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