Risposte:
Ci sono alcune cose che stanno succedendo.
Innanzitutto, Scala consente di omettere punti e parentesi da molte chiamate di metodo, quindi 20 secondsequivale a 20.seconds()*.
In secondo luogo, viene applicata una "conversione implicita". Poiché 20è un Inte Intnon ha alcun secondsmetodo, il compilatore cerca una conversione implicita che accetta Inte restituisce qualcosa che ha un secondsmetodo, con la ricerca vincolata dall'ambito della chiamata del metodo.
Hai importato DurationInt nel tuo ambito. Poiché DurationIntè una classe implicita con un Intparametro, il suo costruttore definisce una Int => DurationIntconversione implicita . DurationIntha un secondsmetodo, quindi soddisfa tutti i criteri di ricerca. Pertanto, il compilatore riscrive la chiamata come new DurationInt(20).seconds**.
* Lo dico liberamente. 20.seconds()non è effettivamente valido poiché il secondsmetodo non ha un elenco di parametri e pertanto i parentesi devono essere omessi nella chiamata del metodo.
** In realtà, questo non è del tutto vero perché DurationIntè una classe di valore, quindi il compilatore eviterà di racchiudere l'intero se possibile.
new DurationInt(20).seconds()quanto tu sappia come lo fa)
secondsmetodo è definito senza parentesi, quindi chiamarlo con parentesi è un errore.
20.seconds()in Scala, solo che il compilatore sta traducendo la chiamata in quel modo. Vale la pena sottolineare che Scala richiede di omettere le parentesi se il metodo corrispondente non ha un elenco di parametri, come in questo caso.
La "magia" che sta succedendo lì si chiama "conversione implicita". Stai importando le conversioni implicite e alcune gestiscono la conversione tra Int (e Double) in Duration. Ecco di cosa hai a che fare.
import scala.concurrent.duration._risolva 20 secondsma l'importazione del tratto DurationConversionsnon lo fa? EDIT : ho appena capito cosa stanno realmente importando DurationInt. Immagino che sia perché non puoi importare il tratto reale? Solo un'implementazione concreta del tratto?