问题描述
scala的方法mkNumericOps
和mkOrderingOps
.math.Integral 的用途以及如何使用它们?
What do methods mkNumericOps
andmkOrderingOps
of scala.math.Integral do and how can we use them?
我知道可以将函数和对象方法声明为implicit
并用于隐式转换.但是我不明白为什么将 traits方法声明为implicit
.
I understand that functions and object methods can be declared implicit
and used for implicit conversion. However I do not understand why traits methods are declared implicit
.
顺便说一句,类方法也可以声明为implicit
吗?
BTW, can class methods be declared implicit
too?
推荐答案
首先,让我们看看它们的声明:
First, let's see their declaration:
implicit def mkNumericOps (lhs: T): IntegralOps
implicit def mkOrderingOps (lhs: T): Ops
它们是隐式的事实意味着它们的目标是提供一些自动值或转换.请注意,它们都从T
转换为其他类型,其中T
是特征的类型参数:Integral[T]
.
The fact that they are implicit means their goal is to provide some automatic value or conversion. Note that they both convert from T
to some other type, where T
is the type parameter of the trait: Integral[T]
.
因此,如果您有Integral[Int]
,则mkNumericOps
将为您提供从Int
到IntegralOps
的自动转换.这意味着您将能够从Int
上的IntegralOps
或Ops
调用方法(或任何Integral
的类型).
So, if you have Integral[Int]
, then mkNumericOps
will give you an automatic conversion from Int
to IntegralOps
. That means you'll be able to call methods from IntegralOps
or Ops
on an Int
(or whatever it is the type of your Integral
).
现在,让我们看看这些是什么方法:
Now, let's see what methods are these:
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
上定义了!那么,为什么以及为什么会使用它们呢?这是一个示例:
These are from IntegralOps
, which extends Ops
. An interesting thing about them is that many of them are already defined on Int
! So, how and why one would use them? Here's an example:
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
.
So, given any type T
for which there's an Integral[T]
implicitly available, you can pass a list of that type to sum
.
如果另一方面,如果我将我的方法专用于类型Int
,则可以在没有Integral
的情况下编写该方法.另一方面,我无法编写对Int
,Long
和BigInt
都适用的内容,因为它们没有共享定义方法+
的共同祖先(更不用说"0"了)
If, on the other hand, I made my method specific for the type Int
, I could write it without Integral
. On the other hand, I can't write something that will work for both Int
and Long
and BigInt
, because they do not share a common ancestor defining the method +
(much less a `zero´).
上面的foldLeft
有效翻译为:
list.foldLeft(integral.zero)((x, y) => mkNumericOps(x).+(y))
这篇关于关于scala.math.Integral的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!