• Github 中文镜像
Sign inSign up
Watch966
Star102.4k
Fork61.8k
Tag: rust
Switch branches/tags
Branches
Tags
  • master
K / Rust HashSet BTreeSet insert 避坑小记.md
移动浏览 Clone
加载中...
到移动设备上浏览
49 lines 2.77 kB
First commit on 22 Nov 2023

    我有个简单的结构体,其中两个字段做 ID,用 Set 在内存中当数据库作高速缓存。

    避坑点:SetMapinsert 不一样。更新数据时,须先 removeinsert,否则 Set 不会插入新值,或者用 replace。即 Map::insertSet::replace 是类似的。

    例子:

    use std::{cmp::Ordering, collections::BTreeSet};
    
    #[derive(Clone, Copy, Eq)]
    struct A {
        pub a: u8,
        pub b: u8,
        pub c: u8,
    }
    
    impl Ord for A {
        fn cmp(&self, other: &Self) -> Ordering {
            match self.a.cmp(&other.a) {
                Ordering::Equal => self.b.cmp(&other.b),
                x => x,
            }
        }
    }
    
    impl PartialOrd for A {
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }
    
    impl PartialEq for A {
        fn eq(&self, other: &Self) -> bool {
            self.a == other.a && self.b == other.b
        }
    }
    
    #[test]
    fn test_field_c() {
        let mut set = BTreeSet::new();
        let mut data = A { a: 1, b: 2, c: 3 };
        set.insert(data);
        data.c = 4;
        set.insert(data); // 无效
        assert_eq!(3, set.get(&data).unwrap().c);
        set.remove(&data); // 先删除
        set.insert(data);
        assert_eq!(4, set.get(&data).unwrap().c);
        data.c = 5;
        set.replace(data); // 直接替换
        assert_eq!(5, set.get(&data).unwrap().c);
    }