Ответ 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
- это класс значений, поэтому компилятор избегает обертывания целого числа, если это возможно.