Відповіді:
Дещо відбувається.
По-перше, 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риси не робить? EDIT : Щойно зрозумів, що вони насправді імпортують DurationInt. Я здогадуюсь це тому, що ви не можете імпортувати фактичну ознаку? Лише конкретна реалізація риси?