有没有办法区分相同值的不同`Rc`?
Is there a way to distinguish between different `Rc`s of the same value?
这是一个例子:
use std::rc::Rc;
#[derive(PartialEq, Eq)]
struct MyId;
pub fn main() {
let rc_a_0 = Rc::new(MyId);
let rc_a_1 = rc_a_0.clone();
let rc_b_0 = Rc::new(MyId);
let rc_b_1 = rc_b_0.clone();
println!("rc_a_0 == rc_a_1: {:?}", rc_a_0 == rc_a_1);
println!("rc_a_0 == rc_b_0: {:?}", rc_a_0 == rc_b_0);
}
以上两个 println!
打印 true
。有没有办法区分 rc_a_*
和 rc_b_*
指针?
您可以将 &*rc
转换为 *const T
以获得指向基础数据的指针并比较这些指针的值:
use std::rc::Rc;
#[derive(PartialEq, Eq)]
struct MyId;
pub fn main() {
let rc_a_0 = Rc::new(MyId);
let rc_a_1 = rc_a_0.clone();
let rc_b_0 = Rc::new(MyId);
let rc_b_1 = rc_b_0.clone();
println!(
"rc_a_0 == rc_a_1: {:?}",
&*rc_a_0 as *const MyId == &*rc_a_1 as *const MyId
);
println!(
"rc_a_0 == rc_b_0: {:?}",
&*rc_a_0 as *const MyId == &*rc_b_0 as *const MyId
);
}
打印
rc_a_0 == rc_a_1: true
rc_a_0 == rc_b_0: false
与 Dogbert 相同的答案,但可能更简洁一些:
use std::ptr;
println!(
"rc_a_0 == rc_a_1: {:?}",
ptr::eq(rc_a_0.as_ref(), rc_a_1.as_ref())
);
println!(
"rc_a_0 == rc_b_0: {:?}",
ptr::eq(rc_a_0.as_ref(), rc_b_0.as_ref())
);
rc_a_0 == rc_a_1: true
rc_a_0 == rc_b_0: false
简而言之,您想要引用相等,而不是值相等。原始指针的值是内存地址,所以比较原始指针的值相当于引用相等。
另请参阅:
2017稳定更新(2020年)。
在 Rust 1.17 及以后版本中,您可以使用 Rc::ptr_eq
. It does the same as ptr::eq
,无需将 Rc
转换为引用或指针。
参考平等
正如其他答案提到的 Rc::ptr_eq
(和 ptr::eq
)检查引用是否相等,即两个引用 "point" 是否指向同一地址。
let five = Rc::new(5);
let same_five = Rc::clone(&five);
let other_five = Rc::new(5);
// five and same_five reference the same value in memory
assert!(Rc::ptr_eq(&five, &same_five));
// five and other_five does not reference the same value in memory
assert!(!Rc::ptr_eq(&five, &other_five));
示例来自 Rust Rc::ptr_eq
文档。
价值观平等
Rc
实现了PartialEq
,所以只要一如既往地使用==
来进行值相等,即值是否相等,与它们是否引用内存中的相同地址无关.
use std::rc::Rc;
let five = Rc::new(5);
let other_five = Rc::new(5);
let ten = Rc::new(10);
assert!(five == other_five);
assert!(ten != five);
assert!(ten != other_five);
这是一个例子:
use std::rc::Rc;
#[derive(PartialEq, Eq)]
struct MyId;
pub fn main() {
let rc_a_0 = Rc::new(MyId);
let rc_a_1 = rc_a_0.clone();
let rc_b_0 = Rc::new(MyId);
let rc_b_1 = rc_b_0.clone();
println!("rc_a_0 == rc_a_1: {:?}", rc_a_0 == rc_a_1);
println!("rc_a_0 == rc_b_0: {:?}", rc_a_0 == rc_b_0);
}
以上两个 println!
打印 true
。有没有办法区分 rc_a_*
和 rc_b_*
指针?
您可以将 &*rc
转换为 *const T
以获得指向基础数据的指针并比较这些指针的值:
use std::rc::Rc;
#[derive(PartialEq, Eq)]
struct MyId;
pub fn main() {
let rc_a_0 = Rc::new(MyId);
let rc_a_1 = rc_a_0.clone();
let rc_b_0 = Rc::new(MyId);
let rc_b_1 = rc_b_0.clone();
println!(
"rc_a_0 == rc_a_1: {:?}",
&*rc_a_0 as *const MyId == &*rc_a_1 as *const MyId
);
println!(
"rc_a_0 == rc_b_0: {:?}",
&*rc_a_0 as *const MyId == &*rc_b_0 as *const MyId
);
}
打印
rc_a_0 == rc_a_1: true
rc_a_0 == rc_b_0: false
与 Dogbert 相同的答案,但可能更简洁一些:
use std::ptr;
println!(
"rc_a_0 == rc_a_1: {:?}",
ptr::eq(rc_a_0.as_ref(), rc_a_1.as_ref())
);
println!(
"rc_a_0 == rc_b_0: {:?}",
ptr::eq(rc_a_0.as_ref(), rc_b_0.as_ref())
);
rc_a_0 == rc_a_1: true
rc_a_0 == rc_b_0: false
简而言之,您想要引用相等,而不是值相等。原始指针的值是内存地址,所以比较原始指针的值相当于引用相等。
另请参阅:
2017稳定更新(2020年)。
在 Rust 1.17 及以后版本中,您可以使用 Rc::ptr_eq
. It does the same as ptr::eq
,无需将 Rc
转换为引用或指针。
参考平等
正如其他答案提到的 Rc::ptr_eq
(和 ptr::eq
)检查引用是否相等,即两个引用 "point" 是否指向同一地址。
let five = Rc::new(5);
let same_five = Rc::clone(&five);
let other_five = Rc::new(5);
// five and same_five reference the same value in memory
assert!(Rc::ptr_eq(&five, &same_five));
// five and other_five does not reference the same value in memory
assert!(!Rc::ptr_eq(&five, &other_five));
示例来自 Rust Rc::ptr_eq
文档。
价值观平等
Rc
实现了PartialEq
,所以只要一如既往地使用==
来进行值相等,即值是否相等,与它们是否引用内存中的相同地址无关.
use std::rc::Rc;
let five = Rc::new(5);
let other_five = Rc::new(5);
let ten = Rc::new(10);
assert!(five == other_five);
assert!(ten != five);
assert!(ten != other_five);