In the following snippet of code, Rust complains that the return types do not match.
let line = String::new(); // assume string has content
let line: String = line.bytes()
.flat_map(|b| {
if b > 0x7F {
format!("M-{}", char::from(b - 0x7F)).bytes()
}
else {
[b].into_iter() // error happens here
}
})
.map(|b| { char::from(b) })
.collect();
The error is the following:
if
and else
have incompatible types
expected type std::str::Bytes<'_>
found struct std::slice::Iter<'_, u8>
How can this be avoided?
vorner
January 3, 2021, 8:25pm
2
You can use either , wrapping each variant into Left and Right respectively. If you have more than two, you can implement an enum manually, or set Either.
Or you can return Box<dyn Iterator<Item = Whatever>>
.
1 Like
I think beyond the first issue (different types returned by the different branches of the if
/else
there is also a problem with ownership.
In a first attempt I was able to get this to compile:
fn main() {
let line = String::new(); // assume string has content
let line: String = line
.bytes()
.flat_map(|b| {
if b > 0x7F {
format!("M-{}", char::from(b - 0x7F)).into_bytes()
} else {
vec![b]
}
})
.map(|b| char::from(b))
.collect();
}
(Playground )
I think this is probably not the prettiest solution because it allocates intermediate vectors in the loop. It might help you as a compiling starting point, however.
Either helped. Thank you!
H2CO3
January 3, 2021, 9:04pm
5
Here's a version that doesn't allocate :
fn main() {
let line = String::from("áÁbBcCeEéÉfF");
let line: String = line
.bytes()
.flat_map(|b| {
if b > 0x7F {
Left("M-".bytes().chain(once(b - 0x7F)))
} else {
Right(once(b))
}
})
.map(char::from)
.collect();
println!("{}", line);
}
2 Likes
The auto_enums
crate can also be used to create bespoke anonymous enums.
1 Like
system
Closed
April 3, 2021, 9:06pm
7
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.