Qual è la regola per le parentesi nel richiamo del metodo Scala?

Non è elencato un metodo che converte qualcosa in una lista?

Se sì, perché non posso usare la parentesi con esso? Devo mancare qualcosa di più fondamentale qui.

Ecco l’esempio:

val l = Array(1,2,3).toList // works fine val l = Array(1,2,3).toList() // gives the error below 

Non sono disponibili argomenti sufficienti per il metodo: (n: Int) Int in tratto LinearSeqOptimized. Parametro valore non specificato n.

Se un metodo è definito come

 def toList = { /* something */ } 

allora deve essere chiamato come

 object.toList 

senza parentesi extra. Diciamo che questo metodo ha zero liste di parametri .

Potremmo anche definire un elenco di parametri ma non inserire nulla in esso:

 def toList() = { /* something */ } 

Ora, potremmo chiamare entrambi

 object.toList() object.toList 

poiché Scala consente la scorciatoia di omettere le parentesi sulle chiamate di metodo.

Per quanto riguarda la JVM, non c’è differenza tra la prima definizione (“liste di parametri zero”) e la seconda (“una lista di parametri vuota”). Ma Scala mantiene una distinzione. Se questa è una buona idea o no è discutibile, ma la motivazione potrebbe essere più chiara quando ti rendi conto che possiamo anche

 def toList()() = { /* something */ } 

che è noto come due elenchi di parametri vuoti e quindi ne chiama uno qualsiasi

 object.toList()() object.toList() object.toList 

e ora, se dovessimo convertire questo in una funzione, dovremmo digitare come

 () => () => T /* T is the return value of the something */ 

mentre la seconda definizione sarebbe

 () => T 

che è chiaramente diverso dal punto di vista concettuale, anche se praticamente lo usi allo stesso modo (non inserire nulla e prima o poi uscire da una T ).

Comunque, toList non ha bisogno di parametri, e lo standard di Scala è di lasciare il paren a meno che il metodo non cambi l’object stesso (piuttosto che restituire qualcosa), quindi è def toList senza alcun parens in seguito. E quindi puoi chiamarlo solo come object.toList .

La tua seconda linea è in realtà interpretata come

 val l = Array(1,2,3).toList.apply() 

poiché foo(x) è la syntax “magica” per foo.apply(x) .

Ecco perché il compilatore si lamenta di “argomenti non sufficienti”, poiché il metodo di applicazione sugli elenchi richiede un argomento.

Quindi puoi scrivere ad esempio:

 scala> val i = Array(1, 2, 3).toList(1) i: Int = 2 

Lasciatemi rispondere dalla prospettiva di stile di codifica Scala.

La guida allo stile Scala dice …

Ometti le parentesi vuote, da utilizzare solo quando il metodo in questione non ha effetti collaterali (puramente funzionali). In altre parole, sarebbe accettabile omettere le parentesi quando si chiama queue.size, ma non quando si chiama println ().

Osservare religiosamente questa convenzione migliorerà notevolmente la leggibilità del codice e renderà molto più facile comprendere a colpo d’occhio l’operazione più basilare di ogni metodo dato. Resisti all’impulso di omettere le parentesi semplicemente per salvare due personaggi!