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