Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to distinguish between different `Rc`s of the same value?

Here's an example:

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);
}

Both println!s above print true. Is there a way distinguish between the rc_a_* and rc_b_* pointers?

like image 836
ynimous Avatar asked Jun 08 '16 15:06

ynimous


People also ask

What is RC differentiator?

The passive RC differentiator is a series connected RC network that produces an output signal which corresponds to the mathematical process of differentiation.

In which condition an RC circuit acts as differentiator?

If time constant of the RC HPF is very much smaller than time period of the input signal, then circuit behaves as a differentiator. Then the voltage drop across R is very small when compared to the drop across C. Where τ=RC the time constant of the circuit.

How do you find the potential difference in an RC circuit?

This equation can be used to model the charge as a function of time as the capacitor charges. Capacitance is defined as C=q/V, so the voltage across the capacitor is VC=qC. Using Ohm's law, the potential drop across the resistor is VR=IR, and the current is defined as I=dq/dt.

What does RC value mean?

The RC time constant is a measure that helps us figure out how long it will take a cap to charge to a certain voltage level. The RC constant will also have some handy uses in filtering that we'll see later on. Calculating the RC is straight forward -- multiply the capacitance C, in Farads, by the resistance R, in Ohms.


3 Answers

2017 stabilization update (in 2020).

In Rust 1.17 and forward, you can use Rc::ptr_eq. It does the same as ptr::eq, without the need of converting the Rc to a reference or pointer.

Reference Equality

As the other answers mention Rc::ptr_eq (and ptr::eq) checks for reference equality, i.e. whether the two references "point" to the same address.

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));

The example is from the Rust Rc::ptr_eq docs.

Value Equality

Rc implements PartialEq, so simply use == as always, to perform value equality, i.e. whether the values are equal, irrelevant of whether they reference the same address in memory.

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);
like image 189
vallentin Avatar answered Sep 19 '22 05:09

vallentin


You can cast &*rc to *const T to get a pointer to the underlying data and compare the value of those pointers:

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
    );
}

prints

rc_a_0 == rc_a_1: true
rc_a_0 == rc_b_0: false
like image 35
Dogbert Avatar answered Sep 23 '22 05:09

Dogbert


The same answer as Dogbert, but maybe a bit cleaner:

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

In short, you want reference equality, not value equality. A raw pointer's value is the memory address, so comparing the value of a raw pointer is equivalent to reference equality.

See also:

  • How to check if two variables point to the same object in memory?
  • Why can comparing two seemingly equal pointers with == return false?
like image 26
Shepmaster Avatar answered Sep 22 '22 05:09

Shepmaster