Как выполняется следующее компиляция:
import scala.concurrent.duration._
val time = 20 seconds
Что здесь происходит?
Происходит несколько вещей.
Во-первых, 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
- это класс значений, поэтому компилятор избегает обертывания целого числа, если это возможно.
"Магия", которая происходит там, называется "неявным преобразованием". Вы импортируете неявные преобразования, а некоторые из них обрабатывают преобразование между Int (и Double) в Duration. Это то, с чем вы имеете дело.
import scala.concurrent.duration._
разрешает 20 seconds
а на самом деле импорт черты DurationConversions
- нет? РЕДАКТИРОВАТЬ : Просто понял, что они на самом деле импортируют это DurationInt
. Я предполагаю, что это потому, что вы не можете импортировать настоящую черту? Только конкретная реализация Черты?
new DurationInt(20).seconds()
чтения, чемnew DurationInt(20).seconds()
если вы знаете, как он это делает)