2012-04-01 4 views
5

Ho già letto che l'istruzione if in Scala restituisce sempre un'espressionescala newbie avere problemi con opzione, qual è l'equivalente del operatore ternario

Così sto cercando di fare quanto segue (pseudo codice)

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

sto cercando con

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

ma ottengo questo errore:

illegal start of simple expression 

ordine è un'opzione [String]

Voglio solo avere un parametro opzionale per un metodo, e se questo parametro (in questo ordine caso) non è passato poi basta saltare

cosa sarebbe essere il modo più idiomatico per ottenere ciò che sto cercando di fare?

- modifica -

Credo che mi sono sbrigato troppo chiedere

ho trovato in questo modo,

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

È questo il modo giusto per farlo?

ho pensato mappa è stata destinata ad altri scopi ...

+2

Il motivo per cui il tuo codice non è compilato è perché hai bisogno di parentesi intorno al ' se' espressione. Ma come sottolinea Tomasz Nurkiewicz, ci sono modi migliori per scrivere comunque. –

+1

Chiunque vuole commentare * perché * abbiamo bisogno di parentesi attorno alla if-expression (diversa da "perché compila")? –

+1

@LuigiPlinge questa è solo una speculazione, ma potrebbe essere che volevano evitare la confusione del programmatore su come si associ un'espressione come '1 + if (b) 2 else 3 + 4'. È '1 + (if (b) 2 else 3) + 4' o' 1 + (if (b) 2 else 3 + 4) '? Certamente potresti avere una grammatica che risolve questa ambiguità (Haskell lo fa), ma ciò non significa che le persone non farebbero errori perché hanno assunto un comportamento diverso. –

risposta

11

Prima di tutto non si utilizza Option[T] idiomaticamente, provate questo:

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

o con sintassi diversa:

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

Che è più o meno equivalente a:

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

Dai un'occhiata allo scala.Option Cheat Sheet. Ma se si vuole veramente andare il modo brutto di if s (tra parentesi mancanti intorno if):

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

Grazie mille, Tomasz, l'ho appena trovato su google ... E sì, sto cercando di imparare il modo più idiomatico di lavorare con Scala ... – opensas

0

... o, se si vuole veramente per impressionare i vostri amici:

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

(I raccomanderei comunque la risposta di Tomasz, ma penso che questo non sia incluso nel cheat di scala.Option, quindi ho pensato di menzionarlo)

+1

Se stai andando piega, perché non usare il prefisso come valore iniziale e fare tutto in una volta? 'val sql = order.foldLeft (" seleziona * da xx ") ((_, b) =>" ordina da "+ b)' –

+0

@AndrzejDoyle hai ragione, questo è un modo per farlo ... ero immaginando che questo sia parte di una query più ampia costruita dinamicamente in cui si ha una funzione che costruisce solo la parte "order by", un'altra che costruisce le clausole "where" e le metti tutte insieme alla fine –