2017-06-09 4 views
0

ich mit Operatorpräzedenz in Scala experimentiert, und es ist etwas seltsam hier passiert:Operator Vorrang in scala seltsam verhält

class Op{ 
    def +(that:Op):Op={println("called +");this} 
    def -(that:Op):Op={println("called -");this} 
    def *(that:Op):Op={println("called *");this} 
    def /(that:Op):Op={println("called /");this} 
    def %(that:Op):Op={println("called %");this} 
} 

val op = new Op; 
op+op-op*op/op%op ; 
op+op*op ; 

Für die erste Zeile, die Ausgabe ist:

called + 
called * 
called/
called % 
called - 

(Hinweis + wird vor * aufgerufen.) Für die zweite Zeile ist der Ausgang jedoch:

called * 
called + 

(* heißt vor +.) Ich glaube von dem, was ich lese here, dass * vor + aufgerufen werden sollte. Habe ich etwas falsch gemacht?

+0

@puhlen es gibt nichts seltsames oder Buggy, Anrufe werden nach Priorität gruppiert und dann von links nach rechts ausgewertet, wie erwartet, siehe das Ende meiner Antwort. –

Antwort

4

Scala gruppiert den Ausdruck nach Priorität, wertet dann die Gruppen streng von links nach rechts aus und hält somit an der Rangfolge fest.

Ihr zweiter Anruf entspricht

op.+(op.*(op)) 

, die von innen nach außen ausgewertet wird.

das gleiche mit den ersten Anruf:

op+op-op*op/op%op 

, die angewendet wird, mit Vorrang

op+op-(op*op/op%op) 

oder

(op+op).-(op*op/op%op) 

oder

// 1  5 2  3  4 
op.+(op).-(op.*(op)./(op).%(op)) 
+0

Lesen Sie die Frage, das ist nicht worum gefragt wird. op + op - op * op erzeugt '+ * -' wie es kompiliert zu' op. + (op) .- (op * (op)) ' – puhlen

+0

Ich habe die op verstanden um diese Frage zu stellen – Adrian

+0

@puhlen was meinst du mit "der ganze Ausdruck"? Ich sehe keinen anderen Weg, dies zu sequenzieren. Scala geht nicht von einer Kommutativität aus, so dass es die Schritte (2, 3, 4) vor Schritt 1 nicht korrekt bewertet, sondern sich, falls anwendbar, streng von links nach rechts hält. –