Как работает "20 секунд" в Scala?

Как выполняется следующее компиляция:

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. Это то, с чем вы имеете дело.