¿Cuál es la regla para el paréntesis en la invocación del método Scala?

¿No es necesario incluir un método que convierta algo en una lista?

Si es así, ¿por qué no puedo usar paréntesis con él? Debo extrañar algo más fundamental aquí.

Aquí está el ejemplo:

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

No hay suficientes argumentos para aplicar el método: (n: Int) Int in trait LinearSeqOptimized. Parámetro de valor no especificado n.

Si un método se define como

 def toList = { /* something */ } 

entonces debe llamarse como

 object.toList 

sin paréntesis adicionales. Decimos que este método tiene cero listas de parámetros .

También podríamos definir una lista de parámetros pero no poner nada en ella:

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

Ahora, podríamos llamar a cualquiera de

 object.toList() object.toList 

ya que Scala permite el acceso directo de omisión de paréntesis en las llamadas a métodos.

En lo que respecta a la JVM, no hay diferencia entre la primera definición (“listas de parámetros cero”) y la segunda (“una lista de parámetros vacía”). Pero Scala mantiene una distinción. Si esto es una buena idea o no es discutible, pero la motivación puede ser más clara cuando te das cuenta de que también podemos

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

que se conoce como dos listas de parámetros vacíos , y luego llamar a cualquiera de

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

y ahora, si tuviéramos que convertir esto en una función, lo escribiríamos como

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

mientras que la segunda definición sería

 () => T 

que es claramente diferente conceptualmente, incluso si prácticamente lo usas de la misma manera (no poner nada y tarde o temprano sacar una T ).

De todos modos, toList no necesita ningún parámetro, y el estándar de Scala es dejar los paréntesis a menos que el método cambie el objeto en sí mismo (en lugar de solo devolver algo), por lo que es def toList sin ningún parens después. Y así solo puedes llamarlo como object.toList .

Su segunda línea en realidad se interpreta como

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

ya que foo(x) es syntax “mágica” para foo.apply(x) .

Es por eso que el comstackdor se queja de “no suficientes argumentos”, ya que el método de aplicación en listas toma un argumento.

Por lo tanto, puedes escribir, por ejemplo:

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

Déjame responder desde la perspectiva del estilo de encoding de Scala.

La guía de estilo de Scala dice …

Omitir paréntesis vacíos, solo se utilizará cuando el método en cuestión no tenga efectos secundarios (puramente funcionales). En otras palabras, sería aceptable omitir paréntesis al llamar a queue.size, pero no al llamar a println ().

La observación religiosa de esta convención mejorará dramáticamente la legibilidad del código y hará que sea mucho más fácil entender a simple vista la operación más básica de cualquier método dado. ¡Resista el impulso de omitir paréntesis simplemente para guardar dos caracteres!