scala.math.Integral的mkNumericOps
和mkOrderingOps
方法有什么作用,我们如何使用它们?
我知道可以将函数和对象方法声明为implicit
并用于隐式转换。但是我不明白为什么将traits方法声明为implicit
。
顺便说一句,类方法也可以声明为implicit
吗?
最佳答案
首先,让我们看看他们的声明:
implicit def mkNumericOps (lhs: T): IntegralOps
implicit def mkOrderingOps (lhs: T): Ops
它们是隐式的事实意味着它们的目标是提供一些自动值或转换。请注意,它们都从
T
转换为其他类型,其中T
是特征的类型参数:Integral[T]
。因此,如果您有
Integral[Int]
,那么mkNumericOps
将为您提供从Int
到IntegralOps
的自动转换。这意味着您将能够从IntegralOps
(或任何Ops
的类型)上的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
这些来自
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)(_ + _)
}
因此,对于任何隐含可用
T
的Integral[T]
类型,您都可以将该类型的列表传递给sum
。另一方面,如果我使我的方法专用于
Int
类型,则可以不用Integral
编写它。另一方面,我无法编写适用于Int
以及Long
和BigInt
的内容,因为它们没有共享定义方法+
的共同祖先(更不用说“0”了)。上面的
foldLeft
有效地翻译为:list.foldLeft(integral.zero)((x, y) => mkNumericOps(x).+(y))