2015-08-07 13 views
6

Volevo verificare alcune best practice della programmazione Scala, poiché sono nuovo di Scala. Ho letto online su come Scala non usa in genere le eccezioni tranne che per circostanze "eccezionali" (che non includono il controllo dei parametri). Proprio ora nel mio progetto sto usando un sacco di require, quindi mi sto chiedendo quale sarebbe il modo migliore per il controllo dei tipi.Scala Costruttore/Metodo Parametro Controllo

Per esempio, se ho una classe

class Foo(String bar){ 
    require(StringUtils.isNotEmpty(bar), "bar can't be empty") 
} 

quali sono le mie alternative al controllo bar? Creo un oggetto companion come

Object Foo { 
    def apply(bar: String) = Try[Foo] { 
    bar match = { 
     case null => Failure("can't be null") 
     //rest of checks 
     case _ => Success[Foo] 
    } 
} 

Oppure dovrei usare Opzione invece?

Inoltre, per i metodi scala, come posso controllare il parametro del metodo? Se restituisco già un'opzione, restituisco un'opzione vuota solo se ottengo un parametro errato? Non significherebbe che devo verificare un'opzione vuota quando uso il ritorno del metodo e non farei un'eccezione per consentire un messaggio più specifico? (ad esempio, l'eccezione di runtime non può utilizzare valori null).

+1

mi meraviglio anche di questo – iCodeLikeImDrunk

+0

@eddiemundorapundo come funzionerebbe per i metodi? Per le classi che vorrei usare si applica giusto? – jstnchng

+0

ugh scusa per aver cancellato il mio commento Non avevo visto Try/Success/Failure dall'ultima volta che ho usato Scala. Prova/Successo/Guasto sembra essere come l'opzione. Nel tuo esempio sembra che dovresti ottenereOrElse() insieme a Foo() per ottenere un oggetto Foo o potresti fare qualcosa con l'oggetto Foo direttamente usando Foo(). FlatMap (...) e ritorna ancora un'altra Prova (che potrebbe provenire dai tuoi metodi) quindi concatena più mappe/filtri/whatevers. – eddiemundorapundo

risposta

2

Penso che la parte Success dell'oggetto companion possa restituire anche l'oggetto Foo()?

Object Foo { 
     def apply(bar: String) = Try[Foo] { 
     bar match = { 
      case null => Failure("can't be null") 
      //rest of checks 
      case _ => Success[Foo](new Foo(bar)) 
     } 
    } 

di usarlo si potrebbe fare qualcosa con la Success si ottiene da Foo (bar):

val hehe = Foo(bar).map(foo => foo.someString()).getOrElse('failed') 

I metodi Try sarà avvolgere automaticamente le eccezioni generate dal someString() o qualsiasi altra cosa che si' stai facendo all'interno di Fallimenti. Se si desidera verificare i parametri di foo.someString(), si dovrebbe fare qualcosa di simile al tuo metodo apply(). Non è molto diverso dal lancio di eccezioni sulle condizioni, ma penso che sia più bello perché i "blocchi catch" si trovano in recover() o recoverWith(). È sempre possibile uscire dallo Try utilizzando getOrElse() se il codice non è stato progettato per concatenare Try s dall'alto verso il basso.

+0

Whoops, sì, voleva che restituisse anche un nuovo oggetto foo. Quindi, quando voglio creare un nuovo oggetto Foo, 'val hehe = Foo (bar)' mi darà un errore se passo una variabile cattiva e un successo altrimenti? Cos'è 'someString()'? – jstnchng

+0

Oh scusa 'someString()' è solo un metodo di esempio che potrebbe avere 'foo'. Sì quando 'bar' è' null' 'Foo (bar)' restituirà un 'Failure' che è un'istanza di' Try' che ha metodi come 'map()'. Quando usi metodi come 'map()' su un 'Failure' restituirà lo stesso' Fallimento'. Quindi puoi pensare ad esso come una pipeline in cui quando una parte della pipa restituisce un "guasto", tutte le altre parti del tubo passeranno quel "guasto". Ovunque tu voglia gestire l'errore nella pipeline, puoi inserire 'recover()' o 'recoverWith()'. – eddiemundorapundo

Problemi correlati