Вопрос про scala.math.Integral

Что делают методы mkNumericOps а такжеmkOrderingOps из scala.math.Integral делать и как мы можем их использовать?

Я понимаю, что функции и методы объекта могут быть объявлены implicit и используется для неявного преобразования. Однако я не понимаю, почему методы признаков объявлены implicit,

Кстати, могут ли быть объявлены методы класса implicit тоже?

1 ответ

Решение

Во-первых, давайте посмотрим на их объявление:

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потому что они не имеют общего предка, определяющего метод + (намного меньше "ноль").

foldLeft вышеприведенное эффективно переводится как это:

list.foldLeft(integral.zero)((x, y) => mkNumericOps(x).+(y))
Другие вопросы по тегам