Il problema
In un mio progetto scritto con il linguaggio Rust
(un’utilità a riga di comando chiamata timetrack)
avevo bisogno di convertire una stringa in una data. Il tipo di partenza
era &Option<String>, mentre il tipo che volevo raggiungere era
Option<Datetime>. Per effettuare operazioni sui valori all’interno di
un Option, possiamo usare la funzione .map(), passandogli una closure.
L’unico problema era che la funzione per convertire la stringa in una data
avrebbe potuto fallire, quindi ritornava un valore Result.
Volevo mantenere un codice conciso che mi permettesse di fare il bubble-up
dell’errore, ma inizialmente il fatto di avere il valore Result
annidato all’interno dell’Option mi aveva bloccato per un po’.
Una soluzione spiacevole
Una possibilità era quella di estrarre il valore facendo un match:
// la variabile `at` è il valore che volevo convertire, ha il tipo `&Option<String>`
// `.as_ref()` serve solo per trasformare `&Option<T>` in `Option<&T>`.
let parsed_result = at.as_ref().map(|time_str| parse(time_str));
let target_time = match parsed_result {
Some(Ok(res)) => Some(res), // Estraiamo il valore se è tutto ok
Some(Err(e)) => return Err(e), // Interrompiamo l'esecuzione e ritorniamo l'errore se ha fallito
None => None
};
Una soluzione idiomatica
Una soluzione più idiomatica e concisa consiste nell’usare la funzione
transpose(). Questa funzione converte Option<Result<T>> in Result<Option<T>>
(e viceversa). Dopo aver effettuato la trasposizione, possiamo semplicemente usare
l’operatore ? per ritornare l’errore nel caso che l’operazione all’interno della
closure fallisca.
Quindi ecco la seconda, migliore, soluzione:
let target_time = at.as_ref()
.map(|time_str| parse(time_str))
.transpose()?;
Questo è più o meno il codice che ho utilizzato in vari punti del mio progetto, fra cui questa riga nel file principale.
Pillole di rust
Questa nuova rubrica si distoglie un po’ dagli argomenti che tratto generalmente nel mio sito. Comunque, ultimamente sto programmando parecchio in Rust per dei progetti personali, e mi sto trovando davvero bene!
Quindi, ho deciso di condividere ogni tanto qualche chicca che scopro mentre continuo la mia immersione in questo linguaggio. Generalmente, saranno piccoli suggerimenti e scoperte utili a sviluppatori rust intermedi. In pratica, se siete nuovi al linguaggio Rust, questi articoli potrebbero confondervi, mentre se siete molto esperti probabilmente queste cose le saprete già. Comunque, immagino ci siano diversi sviluppatori che, come me, si ritrovano nel mezzo.
Spero possa piacervi!
