Shouldn't I use ref to ref like &&str?

Hello, I'm a noob programmer.

I made a HashSet with a vector of &strs and it gave me HashSet<&&str>.

My code has many objects like this. (&&&str, &&i64, etc)

Should I avoid doing this?

Thank you in advance.

An example code

let mut read_var_map:HashMap<&str, Vec<&str>> = HashMap::new();
// ...
// ... codes to add key, value pairs...
// ...
for qname in read_var_map.keys() {
    // The below hash set has &&str. 
    // qname is a &&str too. 
    let var_keys_for_a_read: HashSet<&&str> = HashSet::from_iter(read_var_map.get(qname.deref()).unwrap());
}
    // I have no idea that I should map and deref the &&str to &str or leave it as it is when creating HashSet.
    // I think this case will happen often, because I get values from vectors ,hashmaps etc.

Can you provide some example code to demonstrate what you describe?

2 Likes

In general, it's not an error in itself to create references to references. This comes up a lot in generic code, for example, when the composition of two borrowing abstractions results in a &&T (eg. the argument of the closure in array.iter().filter(|item| ...)).

However, if you are just creating nested references for no good reason, then of course you shouldn't. But this isn't something that is specific to references. If you need something, use it. If you don't need it, don't use it just for the sake of using it.

4 Likes

added some codes in the above.

You can (and probably should?) use Iterator::copied to remove one level of indirection:

use std::collections::HashSet;

fn main() {
    let input: Vec<&str> = vec![&"ABC"];
    let _set1: HashSet<&&str> = HashSet::from_iter(input.iter());
    let _set2: HashSet<&str> = HashSet::from_iter(input.iter().copied());
}

(Playground)


I think in your example, you have a &Vec<&str>, so you'll need to add the extra .iter() (or .into_iter() if you go that way:

use std::collections::HashSet;

fn main() {
    let input: Vec<&str> = vec![&"ABC"];
    let input_ref: &Vec<&str> = &input;
    let _set1: HashSet<&&str> = HashSet::from_iter(input_ref); // doesn't need `.iter()`
    let set2a: HashSet<&str> = HashSet::from_iter(input_ref.iter().copied());
    let set2b: HashSet<&str> = HashSet::from_iter(input_ref.into_iter().copied());
    assert_eq!(set2a, set2b)
}

(Playground)

4 Likes