Sta usando l'opzione # diventa davvero una cattiva idea qui?

4

Sto lavorando su un progetto Scala e Wartremover mostra un errore sull'utilizzo di Option#get nel mio codice:

Option#get is disabled - use Option#fold instead

Mentre capisco come spesso si dovrebbe evitare get , penso che ci siano casi in cui è ragionevole usarlo, come il mio attuale: in primo luogo, creo un elemento di risposta (nel database), quindi voglio restituisci la risposta appena creata leggendola da lì.

def create(answer: Answer): Future[Answer] = {
  writeToDb(answer) // returns Future[Long]
    .flatMap(
      readFromDb(_) // returns Future[Option[Answer]]
        .map(_.get) // Wartremover complains here
    )
}

La mia comprensione è che get dovrebbe generalmente essere evitato perché interrompe il flusso di controllo in caso di None , come viene generata un'eccezione. Tuttavia, mi aspetto che il mio Option qui contenga sempre una risposta, poiché l'ho appena creato. Se non c'è, c'è probabilmente un bug nel mio codice o un problema con il database. In tal caso sarebbe irragionevole ricorrere a un valore predefinito o null . Preferirei lanciare un'eccezione o mappare direttamente a un futuro in errore.

Un'alternativa a get corrisponde in modo esplicito all'opzione:

def create(answer: Answer): Future[Answer] = {
  writeToDb(answer) // returns Future[Long]
    .flatMap(
      readFromDb(_) // returns Future[Option[Answer]]
        .flatMap {
          case Some(answer) => Future.successful(answer)
          case None => Future.failed(
            new IllegalStateException("Failed to load answer after creation"))
        }
    )
}

Tuttavia, questo è molto più verboso pur ottenendo quasi lo stesso risultato di un semplice _.get .

Mi sto perdendo qualcosa qui? O è solo un falso positivo di Wartremover?

    
posta Cedric Reichenbach 01.02.2018 - 08:43
fonte

1 risposta

6

Invece del pattern matching in modo esplicito, puoi scrivere

.getOrElse { throw new IllegalStateException("Failed to load answer after creation") }

Più in generale, quando si ha a che fare con Option / Either / Try puoi spesso evitare la corrispondenza del modello cercando un metodo esistente e riservandolo per i casi in cui devi fare qualcosa di non banale.

Non lo considererei davvero un falso positivo: essere esplicito riguardo all'eccezione è buono e renderà più facile trovare e aggiungere più informazioni di debug se si incontra un problema.

    
risposta data 01.02.2018 - 14:13
fonte

Leggi altre domande sui tag