关于scala.math.Integral的问题

Mic*_*ael 3 scala implicit-conversion

什么方法mkNumericOpsmkOrderingOpsscala.math.Integral做,我们如何使用它们?

我知道可以声明函数和对象方法implicit并将其用于隐式转换.但是我不明白为什么会声明traits方法implicit.

BTW,也可以声明类方法implicit吗?

Dan*_*ral 8

首先,让我们看看他们的声明:

implicit def mkNumericOps (lhs: T): IntegralOps
implicit def mkOrderingOps (lhs: T): Ops
Run Code Online (Sandbox Code Playgroud)

它们是隐含的这一事实意味着它们的目标是提供一些自动价值或转换.请注意,它们都转换T为其他类型,其中T是特征的类型参数:Integral[T].

所以,如果你有Integral[Int],那么mkNumericOps会给你从自动转换IntIntegralOps.这意味着您将能够从IntegralOpsOps在其上调用方法Int(或者您的类型Integral).

现在,让我们看看这些方法是什么:

def % (rhs: T): T
def * (rhs: T): T
def + (rhs: T): T
def - (rhs: T): T
def / (rhs: T): T
def /% (rhs: T): (T, T)
def abs (): T
def signum (): Int
def toDouble (): Double
def toFloat (): Float
def toInt (): Int
def toLong (): Long
def unary_- (): T
Run Code Online (Sandbox Code Playgroud)

这些来自IntegralOps,延伸Ops.关于它们的一个有趣的事情是它们中的许多已经被定义了Int!那么,人们如何以及为何使用它们?这是一个例子:

def sum[T](list: List[T])(implicit integral: Integral[T]): T = {
    import integral._   // get the implicits in question into scope
    list.foldLeft(integral.zero)(_ + _)
}
Run Code Online (Sandbox Code Playgroud)

因此,给定TIntegral[T]隐式可用的任何类型,您可以将该类型的列表传递给sum.

另一方面,如果我使用特定于该类型的方法Int,我可以不用它来编写它Integral.在另一方面,我不能写东西,将两个工作IntLongBigInt,因为他们没有共同的祖先定义的方法+(更不用说`zero').

foldLeft上述有效转化为这样的:

list.foldLeft(integral.zero)((x, y) => mkNumericOps(x).+(y))
Run Code Online (Sandbox Code Playgroud)