如何在不实现PartialOrd的情况下比较Rust中的两个Arc指针?
在Rust中不修改结构体的前提下对Arc进行确定性排序
在C++中可以直接比较指针的内存地址,但Rust的Arc<T>默认会尝试比较指向的T实例内容——当T未实现PartialOrd trait时,就会触发编译错误。要在不修改Dummy结构体的前提下实现Arc<Dummy>的确定性排序,有两种简洁的方案:
方案1:直接比较底层裸指针地址
利用Arc::as_ptr()获取指向内部数据的裸指针,裸指针本身实现了Ord trait,可直接用于比较:
use std::sync::Arc; use std::cmp::Ordering; struct Dummy {} // 定义比较函数,返回Ordering枚举表示排序关系 fn compare_arc_dummy(a: &Arc<Dummy>, b: &Arc<Dummy>) -> Ordering { a.as_ptr().cmp(&b.as_ptr()) } fn main() { let ptr_a = Arc::new(Dummy {}); let ptr_b = Arc::new(Dummy {}); match compare_arc_dummy(&ptr_a, &ptr_b) { Ordering::Less => println!("ptr_a 在排序中位于 ptr_b 之前"), Ordering::Greater => println!("ptr_a 在排序中位于 ptr_b 之后"), Ordering::Equal => println!("ptr_a 和 ptr_b 指向同一个对象"), } }
这种方式基于内存地址排序,结果完全确定,且不需要对Dummy做任何修改。
方案2:用新类型包装实现比较运算符支持
如果希望直接使用<、>等比较运算符,可以通过新类型模式包装Arc<Dummy>,并为包装类型实现PartialOrd、Ord等必要trait:
use std::sync::Arc; use std::cmp; struct Dummy {} // 新类型包装Arc<Dummy>,保留Arc的原有功能 #[derive(Clone, Debug)] struct AddrSortedArc<T>(Arc<T>); // 实现相等性判断 impl<T> PartialEq for AddrSortedArc<T> { fn eq(&self, other: &Self) -> bool { self.0.as_ptr() == other.0.as_ptr() } } impl<T> Eq for AddrSortedArc<T> {} // 实现部分排序 impl<T> PartialOrd for AddrSortedArc<T> { fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) } } // 实现全排序 impl<T> Ord for AddrSortedArc<T> { fn cmp(&self, other: &Self) -> cmp::Ordering { self.0.as_ptr().cmp(&other.0.as_ptr()) } } fn main() { let ptr_a = AddrSortedArc(Arc::new(Dummy {})); let ptr_b = AddrSortedArc(Arc::new(Dummy {})); if ptr_a < ptr_b { println!("ptr_a < ptr_b"); } else if ptr_a > ptr_b { println!("ptr_a > ptr_b"); } else { println!("ptr_a == ptr_b"); } }
新类型模式既不会破坏原Dummy结构体的定义,又能让包装后的类型支持原生比较运算符,排序逻辑同样基于内存地址,具备确定性。
内容的提问来源于stack exchange,提问作者Rahn
相关产品推荐
相关产品推荐

