Как работает «20 секунд» в Scala?

97

Как выполняется следующее компиляция:

import scala.concurrent.duration._

val time = 20 seconds

Что здесь происходит?

Теги:
duration

2 ответа

131
Лучший ответ

Происходит несколько вещей.

Во-первых, Scala позволяет пропускать точки и парсеты во многих вызовах методов, поэтому 20 seconds эквивалентно 20.seconds() *.

Во-вторых, применяется "неявное преобразование". Поскольку 20 является Int и Int не имеет метода seconds, компилятор ищет неявное преобразование, которое принимает Int и возвращает то, что имеет метод seconds, при этом поиск ограничен область вашего вызова метода.

Вы импортировали DurationInt в свой объем. Поскольку DurationInt является неявным классом с параметром Int, его конструктор определяет неявное преобразование Int => DurationInt. DurationInt имеет метод seconds, поэтому он удовлетворяет всем критериям поиска. Поэтому компилятор переписывает ваш вызов как new DurationInt(20).seconds **.

* Я имею в виду это свободно. 20.seconds() на самом деле недействителен, поскольку метод seconds не имеет списка параметров, и поэтому при вызове метода парны должны быть опущены.

** Собственно, это не совсем так, потому что DurationInt - это класс значений, поэтому компилятор избегает обертывания целого числа, если это возможно.

  • 79
    Любая достаточно развитая технология неотличима от магии.
  • 4
    К счастью, большинство IDE способны его различить! Неявные преобразования довольно часто используются в Scala. Если вы просто читаете текстовый файл, это может сбить с толку («откуда взялся этот метод»), но с соответствующей поддержкой инструментов вы сможете найти способ обойти это, и в этот момент Scala может быть красиво осмысленным и лаконичным. (например, 20.seconds гораздо new DurationInt(20).seconds() чтения, чем new DurationInt(20).seconds() если вы знаете, как он это делает)
Показать ещё 3 комментария
6

"Магия", которая происходит там, называется "неявным преобразованием". Вы импортируете неявные преобразования, а некоторые из них обрабатывают преобразование между Int (и Double) в Duration. Это то, с чем вы имеете дело.

  • 0
    Любая идея, почему импорт import scala.concurrent.duration._ разрешает 20 seconds а на самом деле импорт черты DurationConversions - нет? РЕДАКТИРОВАТЬ : Просто понял, что они на самом деле импортируют это DurationInt . Я предполагаю, что это потому, что вы не можете импортировать настоящую черту? Только конкретная реализация Черты?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню