Rust BTreeSet 插入具有重复排名字段的唯一值

问题描述 投票:0回答:1

我需要一个有序集,所以我使用 BTreeSet。我有一个 Item 结构,其中包含唯一的 id 和可能重复的排名字段。我只希望考虑 id 字段的唯一性并在排名字段上对其进行排序,因此我手动实现了 PartialEq、PartialOrd 和 Ord 来执行此操作,但它没有按我的预期工作

代码如下: Rust 游乐场:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=89853e19bb56282226711778c63c0605

use std::cmp::Ordering;
use std::collections::BTreeSet;

#[allow(dead_code)]
fn main() {
    let mut set = BTreeSet::new();
    set.insert(Item {
        id: 0,
        rank: 0,
    });
    set.insert(Item {
        id: 1,
        rank: 1,
    });
    set.insert(Item {
        id: 2,
        rank: 1,
    });
    for item in set.iter() {
        println!("{:?}", item);
    }

}

#[derive(Debug, Eq)]
struct Item {
    id: u32,
    rank: u32,
}

impl PartialEq for Item {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}

impl PartialOrd for Item {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Item {
    fn cmp(&self, other: &Self) -> Ordering {
        self.rank.cmp(&other.rank)
    }
}

我得到了输出

Item { id: 0, rank: 0 }
Item { id: 1, rank: 1 }

当我期待的时候

Item { id: 0, rank: 0 }
Item { id: 1, rank: 1 }
Item { id: 2, rank: 1 }

为什么会发生这种情况以及如何解决这个问题?

rust set b-tree
1个回答
0
投票

发生这种情况是因为您违反了

PartialOrd
的合同之一:

a == b
当且仅当
partial_cmp(a, b) == Some(Equal)
BTreeSet
依赖于那些来保持。

您无法使用

BTreeSet
实现您想要的行为,而应该使用自定义容器。

© www.soinside.com 2019 - 2024. All rights reserved.