Using a HashSet to canonicalize objects in Rust

前端 未结 2 695
無奈伤痛
無奈伤痛 2021-01-21 02:43

As an educational exercise, I\'m looking at porting cvs-fast-export to Rust.

Its basic mode of operation is to parse a number of CVS master files into a intermediate for

2条回答
  •  盖世英雄少女心
    2021-01-21 03:18

    I somewhat disagree with @Shepmaster on the use of unsafe here.

    While right now it does not cause issue, should someone decide in the future to change the use of HashSet to include some pruning (for example, to only ever keep a hundred authors in there), then unsafe will bite you sternly.

    In the absence of a strong performance reason, I would simply use a Rc. You can alias it easily enough: type InternedXXX = Rc;.

    use std::collections::HashSet;
    use std::hash::Hash;
    use std::rc::Rc;
    
    #[derive(PartialEq, Eq, Debug, Hash, Clone)]
    struct CvsNumber(Rc>);
    
    fn intern(set: &mut HashSet, item: T) -> T {
        if !set.contains(&item) {
            let dupe = item.clone();
            set.insert(dupe);
            item
        } else {
            set.get(&item).unwrap().clone()
        }
    }
    
    fn main() {
        let mut set: HashSet = HashSet::new();
        let c1 = CvsNumber(Rc::new(vec![1, 2]));
        let c2 = intern(&mut set, c1);
        let c3 = CvsNumber(Rc::new(vec![1, 2]));
        let c4 = intern(&mut set, c3);
    }
    

提交回复
热议问题