scala.math.IntegralmkNumericOpsmkOrderingOps方法有什么作用,我们如何使用它们?

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

顺便说一句,类方法也可以声明为implicit吗?

最佳答案

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

implicit def mkNumericOps (lhs: T): IntegralOps
implicit def mkOrderingOps (lhs: T): Ops

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

因此,如果您有Integral[Int],那么mkNumericOps将为您提供从IntIntegralOps的自动转换。这意味着您将能够从IntegralOps(或任何Ops的类型)上的IntIntegral调用方法。

现在,让我们看看这些是什么方法:
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

这些来自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)(_ + _)
}

因此,对于任何隐含可用TIntegral[T]类型,您都可以将该类型的列表传递给sum

另一方面,如果我使我的方法专用于Int类型,则可以不用Integral编写它。另一方面,我无法编写适用于Int以及LongBigInt的内容,因为它们没有共享定义方法+的共同祖先(更不用说“0”了)。

上面的foldLeft有效地翻译为:
list.foldLeft(integral.zero)((x, y) => mkNumericOps(x).+(y))

10-04 17:32