Risposte:
Ci sono alcune cose che stanno succedendo.
Innanzitutto, Scala consente di omettere punti e parentesi da molte chiamate di metodo, quindi 20 seconds
equivale a 20.seconds()
*.
In secondo luogo, viene applicata una "conversione implicita". Poiché 20
è un Int
e Int
non ha alcun seconds
metodo, il compilatore cerca una conversione implicita che accetta Int
e restituisce qualcosa che ha un seconds
metodo, con la ricerca vincolata dall'ambito della chiamata del metodo.
Hai importato DurationInt nel tuo ambito. Poiché DurationInt
è una classe implicita con un Int
parametro, il suo costruttore definisce una Int => DurationInt
conversione implicita . DurationInt
ha un seconds
metodo, 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 seconds
metodo 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)
seconds
metodo è 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 seconds
ma l'importazione del tratto DurationConversions
non 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?