2016-07-01 12 views
0

Ich arbeite in einem groovy/grails-Setup und habe Probleme, eine switch-Anweisung für einen String-Wert auszuführen.Das Einschalten des String-Wertes führt zu unerwarteten Ergebnissen in Groovy

Grundsätzlich durchlaufen ich die Attributnamen in einer Webservice-Antwort, um festzustellen, ob sie vordefinierten Zuordnungen entsprechen, die pro Benutzer konfiguriert sind. Wenn sie ein Mapping für dieses Feld erstellt haben, ziehe ich den Wert aus der Antwort und verwende sie an anderer Stelle.

Der Code sieht etwa so aus:

switch(attributeName) 
{ 
    case {attributeName} : 
     log.info("Currently switching on value... ${attributeName}") 

    case user.getFirstNameMapping(): 
     model.user.userInfo.firstName = attributeValue 
     break 
    case user.getLastNameMapping(): 
     model.user.userInfo.lastName = attributeValue 
     break 
    case user.getAuthenticationKeyMapping(): 
     model.authenticationValue = attributeValue 
     break 
    case user.getEmailMapping(): 
     model.email = attributeValue.toLowerCase() 
     break 
} 

Der Wert auf (attribute) geschaltet wird, ist vom Typ String und die Getter-Methoden für die Benutzerinstanz auch Typ String zurück.

Basierend auf meinen Nachforschungen und dem Verständnis der Groovy-Sprache sollte das Einschalten eines Objekts wie eines Strings mit String.equals() enden, um den Vergleich zu machen. Das Ergebnis ist jedoch, dass jedes Mal der Fall user.getFirstNameMapping() abgeglichen wird und der Wert im Modell wiederholt überschrieben wird. Daher ist der letzte Wert, der in der Antwort zurückkommt, der zuletzt gespeicherte Wert und keiner der anderen Werte wird gespeichert.

Was interessant ist, dass wenn ich eine if/else-Struktur verwenden und etwas tun, wie folgt aus:

if(attributeName.equals(user.getFirstNameMapping()) 
{ 
    ... 
} 

Es funktioniert jedes Mal gut. Ich habe durch Protokollierung überprüft, dass es sich nicht um etwas Dummes handelt, wie z. B. ein zusätzliches Leerzeichen oder ein Großschreibungsproblem. Ich habe auch versucht, die Dinge zu ändern um den Schalter standardmäßig ausgeführt und ausdrücklich die attribute im Fall wie folgt vergleichen:

switch(true) 
{ 
    case {attributeName} : 
     log.info("Currently switching on value... ${attributeName}") 
    case {user.getFirstNameMapping().equals(attributeName)}: 
     model.user.userInfo.firstName = attributeValue 
     break 
    case {user.getLastNameMapping().equals(attributeName)}: 
     model.user.userInfo.lastName = attributeValue 
     break 
    case {user.getAuthenticationKeyMapping().equals(attributeName)}: 
     model.authenticationValue = attributeValue 
     break 
    case {user.getEmailMapping().equals(attributeName)}: 
     model.email = attributeValue.toLowerCase() 
     break 
} 

Und es immer noch nicht meine Erwartungen in der exakt gleichen Art und Weise gerecht zu werden. Ich frage mich, warum dies das Verhalten ist, wenn die switch-Anweisung einfach equals() verwenden sollte, um die Strings zu vergleichen, und wenn ich sie explizit in einem if/else mit .equals() vergleiche, funktioniert es wie erwartet.

+0

Problem ist nicht in Grails das Problem in der Art und Weise u Schaltergehäuse verwendet, wie Fall {attribute} jedes Mal ausgeführt werden, und wenn Sie der zweite Fall sehen sich auch mit, dass jedes Mal, und dann läuft wird unterbrochen. Drucken Sie daher den Wert von {attributeName}, bevor der Switch gestartet wird. –

Antwort

1

Das Problem ist in Ihrem Switch-Fall.

Werfen Sie einen Blick hier: -

case {attributeName} : 
     log.info("Currently switching on value... ${attributeName}") 

case user.getFirstNameMapping(): 
     model.user.userInfo.firstName = attributeValue 
     break 

Wie Sie Ihr diese beiden Fälle jedes Mal sehen kann, weil der Schaltzustand ist, wird ausgeführt: -

switch(attributeName) 

So ist der erste wird erhalten Spiel und wird laufen, bis es auf Pause stößt; Das ist bei nach Fall 2, d. h. case user.getFirstNameMapping():, also würde ich vorschlagen, dass Sie den Wert von {attributeName} drucken, bevor der swtich beginnt.

Hoffe, dass Ihnen helfen wird.

Dank

0

Ich weiß nicht genau, was Ihr Problem ist, aber die Case-Anweisung funktioniert gut, auch mit Methoden. Siehe mein Beispiel

String something = "Foo" 

class User { 
    String firstName 
    String lastName 
} 

User u = new User(firstName: 'Something', lastName:'Foo') 

switch(something) { 
    case u.getFirstName(): 
    println "firstName: ${u.firstName}" 
    break; 
    case u.getLastName(): 
    println "lastName: ${u.lastName}" 
    break; 
    default: 
    println "nothing..." 
} 

Dieser Code wird LastName wie erwartet drucken.