Ответы:
Происходит несколько вещей.
Во-первых, 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
а на самом деле импорт DurationConversions
Trait - нет? РЕДАКТИРОВАТЬ : только что понял, что они на самом деле импортируют DurationInt
. Я предполагаю, что это потому, что вы не можете импортировать настоящую черту? Только конкретная реализация Черты?