import scala.concurrent.duration._
val time = 20 seconds
Что здесь происходит?
Ответ 1
Происходит несколько вещей.
Во-первых, 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 - это класс значений, поэтому компилятор избегает обертывания целого числа, если это возможно.
Ответ 2
"Магия", которая происходит там, называется "неявным преобразованием". Вы импортируете неявные преобразования, а некоторые из них обрабатывают преобразование между Int (и Double) в Duration. Это то, с чем вы имеете дело.