scala methods call infix-notation

Scala-infijo vs notación de puntos



methods call (4)

¿Hay una mejor práctica para uno sobre el otro? He estado leyendo el libro de Scala por Odersky, et al. y parece que el infijo se usa para muchas de las funciones de la API de colecciones, mientras que el punto está reservado para las funciones definidas por el programador.


Es una cuestión de preferencia personal. Su decisión de usar un estilo u otro debe basarse en lo que hace que su código sea más legible.

Pero tenga en cuenta que la capacidad de dejar el punto y los paréntesis está limitada solo a ciertas construcciones sintácticas, por lo que a veces solo tiene que recurrir a usarlas.


Hay una buena guía de estilo en la documentación oficial del sitio de Scala que describe la notación infija de uso adecuado sobre la notación de puntos.

Notación de sufijo:

names.toList // is the same as names toList // Unsafe, don''t use!

Arity-1:

// right! names foreach (n => println(n)) names mkString "," optStr getOrElse "<empty>" // wrong! javaList add item

Funciones de orden superior:

// wrong! names.map (_.toUpperCase).filter (_.length > 5) // right! names map (_.toUpperCase) filter (_.length > 5)

Métodos simbólicos / Operadores:

// right! "daniel" + " " + "Spiewak" // wrong! "daniel"+" "+"spiewak"


He descubierto que el uso de la notación infija para el map funciona bien cuando estoy creando cartesianos con la biblioteca de gatos . p.ej:

(fetchIt(1) |@| fetchIt(2) |@| fetchIt(3)).map(MyCaseClass)

puedes deshacerte de los paréntesis que lo rodean así:

fetchIt(1) |@| fetchIt(2) |@| fetchIf(3) map MyCaseClass

y en mi opinión, la segunda variante se lee mejor. Una cuestión de gusto, supongo. Solo quería agregar el valor de mis dos centavos.

Lo anterior funciona porque | en "| @ |" tiene una precedencia mayor que m en "mapa". Lea esta parte de la especificación de Scala lang para obtener más detalles:

Si hay varias operaciones infija en una expresión, los operadores con mayor precedencia se unirán más estrechamente que los operadores con menor precedencia.

http://scala-lang.org/files/archive/spec/2.12/06-expressions.html#infix-operations


Personalmente, no tengo reglas duras y rápidas para esto, pero tiendo a usar la notación infija solo con nombres de métodos simbólicos y notación de puntos para los alfanuméricos.

La notación Infix hace que sea engorroso modificar el código más tarde. Aquí hay unos ejemplos.

Imagina que tienes esta línea de código:

xs filter { f } map { g }

Supongamos que en algún momento posterior necesita agregar un toList al final. Lo pones así:

xs filter { f } map { g } toList

Esto puede causar problemas de inferencia de punto y coma. Para evitar estos problemas, coloque un punto y coma o coloque una nueva línea. Ambas opciones son feas, en mi opinión. Para evitar todas estas tonterías, prefiero ir con xs.filter(f).map(g) . Siempre es más fácil refactorizar con esta sintaxis.

Otro ejemplo: digamos que tengo lo siguiente en mi código:

if(foo contains bar) { ..

Diga, necesito negar la condición. Si lo modifico de la siguiente manera:

if(!foo contains bar) { ..

Gorrón. Esto se analiza como (!foo).contains(bar) . No es lo que queríamos

O supongamos que necesita agregar una nueva condición además, y la modifica de modo que:

if(foo contains bar && cond) { ..

Otro fastidio Esto se analiza como foo.contains(bar.&&(cond)) . No es lo que queríamos, otra vez.

Por supuesto, podría agregar un montón de paréntesis, pero sería feo y difícil de leer / editar en comparación con la notación de puntos.

Ahora, todo lo que dije arriba también se aplica a los nombres de métodos simbólicos. Sin embargo, los métodos simbólicos no parecen naturales cuando se usan con sintaxis de punto, por lo que prefiero la sintaxis de infijo para ellos.

Una excepción a la directriz anterior: DSL internas. Por lo general, se elaboran con cuidado para no causar problemas de análisis cuando se escriben de la manera prescrita en su documentación / ejemplos (que generalmente usa notación infija).