No exemplo simplificado a seguir, o compilador reclama que uma ramificação da match
instrução retorna bool
, enquanto a outra retorna ()
.
use std::collections::{HashMap, HashSet};
fn main() {
let available = HashMap::from_iter([(2, "b"), (3, "c"), (4, "d")]);
let mut set = HashSet::new();
for i in [1, 2, 3, 4, 5] {
match available.get(&i) {
Some(s) => set.insert(*s),
None => ()
}
}
}
No entanto, isso resulta em um erro:
error[E0308]: `match` arms have incompatible types
--> src/main.rs:10:21
|
8 | / match available.get(&i) {
9 | | Some(s) => set.insert(*s),
| | -------------- this is found to be of type `bool`
10 | | None => ()
| | ^^ expected `bool`, found `()`
11 | | }
| |_________- `match` arms have incompatible types
Como posso informar ao compilador que a instrução match deve retornar ()
e que o bool
retornado de insert
deve ser ignorado?
A maneira usual seria apenas colocar o braço em um bloco e cobri-lo com um
;
, pois isso suprime o resultado da expressão:Uma alternativa provavelmente menos comum seria alimentar o valor para uma função "convertendo-a" em um
()
exemplodrop
Como alternativa, você pode simplesmente ignorar totalmente a segunda ramificação:
ou use uma função de ordem superior para esse efeito colateral, que embora não seja o mais comum, é uma coisa:
Você pode transformar ambos os blocos em declarações:
Ou você pode converter o
match
para umif
-let
:Ainda outra opção é explorar que
Option
é iterável e&str
éCopy
, então você pode passar a opção retornada poravailable.get()
paraExtend::extend()
:Observe que isso requer anotações de tipo adicionais neste caso específico.
O loop for pode ser reescrito em estilo funcional como