0

I am just starting using rust and discovered the clippy assistant. I am generally very satisfied with its functionalities, but i encountered a recommendation which I do not know if I should follow. while working with a HashMap, I want to test if a stored value (say a f32) respects a condition (say it is greater than 10.). Also, I am not sure that the value is am looking for using its key is already in the HashMap. I wrote:

if mymap.contains_key(k) {
    if *mymap.get(k).unwrap() > 10. {
        // do something
    }
}

Then clippy politely asks me to collapse this if statement into one:

help: collapse nested if block
  |
3 |     if mymap.contains_key(k) && *mymap.get(k).unwrap() > 10. {
4 |         // do something
5 |     }
  |

I feel that collapsing this would bring a chance of *mymap.get(k).unwrap() > 10. being evaluated before mymap.contains_key(k). If so, and if the key is not already in mymap, this would generate an error.

I suppose there exists more elegant ways to do what I am trying to do with combinations of if let or so, but if I wanted to keep my ifs, would it be possible to collapse them, and in which order would the conditions be evaluated ?

trent
  • 25,033
  • 7
  • 51
  • 90
Louis
  • 83
  • 6
  • 2
    Does this help? https://stackoverflow.com/questions/53644809/do-logical-operators-short-circuit-in-rust – Gereon Apr 01 '21 at 14:54
  • 2
    In addition to Gereon's comment, also note that you could eliminate double lookup with `if mymap.get(k).map(|&v| v > 10.).unwrap_or(false) { /* do something */ }`. (Or `if let Some(&v) = mymap.get(k) { if v > 10. { /* do something */ } }`, but then you get to `if`s again.) – user4815162342 Apr 01 '21 at 15:05
  • @Gereon Thank you for the link, it does answer my question. To sum up, only the left part of `mymap.contains_key(k) && *mymap.get(k).unwrap() > 10.` would be evaluated if the key did not belong to the HashMap, therefore not generating any error. – Louis Apr 01 '21 at 15:25
  • 1
    You can check and get together rather than performing double lookup: `if let Some(value) = mymap.get(k) { if value > 10 { … } }`. This one isn't collapsible (yet). – mcarton Apr 01 '21 at 16:28

0 Answers0