2012-04-01 9 views
5

ich bereits gelesen habe, dass die if-Anweisung in scala immer einen Ausdruck gibtscala Neuling Probleme mit Option hat, was ist das Äquivalent des ternären Operators

So den folgenden (Pseudo-Code) Ich versuche

zu tun
sql = "select * from xx" + iif(order.isDefined, "order by " order.get, "") 

ich versuche, mit

val sql: String = "select * from xx" + if (order.isDefined) {" order by " + order.get} else {""} 

Aber ich bekomme diese Fehlermeldung:

illegal start of simple expression 

Auftrag ist eine Option [Zeichenfolge]

Ich möchte nur einen optionalen Parameter auf ein Verfahren haben, und wenn dieser Parameter (in diesem Fall Reihenfolge) ist es nicht übergeben dann nur

überspringen, was würde der idiomatische Weg sein, um zu erreichen, was ich versuche zu tun?

- bearbeiten -

Ich glaube, ich zu viel

zu fragen

ich auf diese Weise gefunden,

val orderBy = order.map(" order by " + _).getOrElse("") 

eilte Ist dies der richtige Weg, es zu tun?

Ich dachte Karte für andere Zwecke gedacht war ...

+2

Der Grund, dass Ihr Code nicht kompiliert ist, weil Sie Klammern um die ' wenn "Ausdruck". Aber wie Tomasz Nurkiewicz betont, gibt es bessere Möglichkeiten, dies zu schreiben. –

+1

Wer möchte kommentieren * warum * wir brauchen Klammern um den if-Ausdruck (anders als "weil es kompiliert")? –

+1

@ LuigiPlinge Dies ist nur Spekulation, aber es könnte sein, dass sie Programmierer Verwirrung vermeiden wollten, wie ein Ausdruck wie '1 + wenn (b) 2 else 3 + 4 'assoziieren würde. Ist es "1 + (wenn (b) 2 sonst 3) + 4" oder "1 + (wenn (b) 2 sonst 3 + 4)"? Sicherlich könnte man eine Grammatik haben, die diese Ambiguität löst (Haskell), aber das heißt nicht, dass die Leute keine Fehler machen würden, weil sie ein anderes Verhalten angenommen hätten. –

Antwort

11

allererst Sie nicht Option[T] idiomatisch verwenden, versuchen Sie dies:

"select * from xx" + order.map(" order by " + _).getOrElse("") 

oder mit unterschiedlicher Syntax:

"select * from xx" + (order map {" order by " + _} getOrElse "") 

Dies entspricht in etwa:

"select * from xx" + order match { 
    case Some(o) => " order by " + o 
    case None => "" 
} 

Werfen Sie einen Blick auf scala.Option Cheat Sheet. Aber wenn Sie wirklich wollen, die hässliche Art und Weise von if s gehen (in Klammern if fehlt):

"select * from xx" + (if(order.isDefined) {" order by " + order.get} else {""}) 
+0

Vielen Dank, Tomasz, ich habe es gerade auf Google gefunden ... Und ja, ich versuche die idiomatische Art zu lernen, mit Scala zu arbeiten ... – opensas

0

... oder, wenn Sie wirklich Ihre Freunde beeindrucken wollen:

order.foldLeft ("") ((_,b)=>"order by " + b) 

(I würde Tomasz 'Antwort immer noch empfehlen, aber ich denke, diese ist nicht in der scala.Option Spickzettel enthalten, so dachte ich, ich würde es erwähnen)

+1

Wenn du willst folden, warum nicht das Präfix als Anfangswert verwenden und das Ganze auf einmal erledigen? 'val sql = order.foldLeft (" wähle * von xx ") ((_, b) =>" order by "+ b)' –

+0

@AndrzejDoyle du hast Recht, das ist ein Weg, es zu tun ... Ich war Stellen Sie sich vor, dass dies Teil einer größeren dynamisch konstruierten Abfrage ist, bei der Sie eine Funktion haben, die nur den "order by" Teil erstellt, eine andere, die die "where" Klauseln erstellt und Sie alle am Ende zusammensetzt –