representar redes que precedencias precedencia para método metodos metodo ejercicio ejemplos ejemplo diagrama scala methods

redes - Scala-método de precedencia



precedencia ejemplos (2)

Este comportamiento se define en el capítulo 6.12.3 Operaciones de infijo de la especificación del lenguaje Scala .

En resumen: los métodos se invocan de izquierda a derecha por defecto con algunas excepciones. Estas excepciones solo se introdujeron para dar prioridad a los operadores matemáticos. Entonces cuando tienes dos funciones llamadas * y + :

a + b * c

Esto siempre será traducido a:

a.+(b.*(c))

Aquí el primer nombre de la función controla la precedencia. Sin embargo, para las funciones ordinarias no puedes controlar el orden. Piénselo, esto en realidad causaría estragos y un código terriblemente imposible de mantener.

Consulte también (¿no está completamente duplicado?): Prioridad del operador en Scala .

Soy nuevo en Scala. Me pregunto si es posible definir alguna prioridad con las llamadas a métodos. Por ejemplo, si tengo la cadena de llamadas de método:

someObject method1 param1 method2 param2 method3 param3

¿Puede esto ser equivalente a lo siguiente?

someObject.method1(param1).method2(param2.method3(param3))

o

someObject method1 param1 method2 (param2 method3 param3)

Así que quiero que el método 3 tenga prioridad sobre el método 2 ...

La razón por la que quiero hacer esto es que quiero desarrollar un DSL, por lo que quiero evitar el uso de puntos y paréntesis tanto como sea posible. Si ustedes encuentran otra solución para mí, no dude en hacérmelo saber.


Tendrá que usar métodos con caracteres de operadores especiales para influir en la prioridad como lo indica Tomasz. Esto es en parte por qué muchos Scala DSL hacen un uso intensivo de los operadores. También por qué algunos DSL son difíciles de leer si no trabajas con ellos diariamente.

Dado el método que usa solo letras, guiones bajos y dígitos: no podrás influir en las cosas, esto es lo que armé para mí después de leer la especificación:

  • Cualquier método que tome un solo parámetro se puede usar como operador de infijo: am(b) se puede escribir amb .
  • Cualquier método que no requiera un parámetro puede usarse como operador de postfix: am puede escribirse am .

  • Los operadores de Postfix tienen menor prioridad que los operadores de infijo , por lo que foo bar baz significa foo.bar(baz) mientras que foo bar baz bam significa (foo.bar(baz)).bam y foo bar baz bam bim significa (foo.bar(baz)).bam(bim) .

Entonces, sin saber en absoluto cuáles son las firmas de su método, el siguiente código (porque es todo alfanumérico):

someObject method1 param1 method2 param2 method3 param3

será analizado como:

someObject.method1(param1).method2(param2).method3(param3)

Si cambia el nombre de method3 a |*| o +:+ o cualquier operador que tenga sentido, puede lograr lo que quiere:

someObject method1 param1 method2 param2 |*| param3 // same as someObject.method1(param1).method2(param2.|*|(param3))

Por ejemplo para ver la diferencia:

implicit def pimp(s:String) = new { def |*|(t:String) = t + s def switch(t:String) = t + s } scala> "someObject" concat "param1" concat "param2" |*| "param3" res2: java.lang.String = someObjectparam1param3param2 scala> "someObject" concat "param1" concat "param2" switch "param3" res3: java.lang.String = param3someObjectparam1param2