Sorry for the long post, but I have a lot of questions about dereferencing and coercion. I’ve spent my last days trying to study them and make a lot of examples and every time that I feel that I got them I always find a situation that get me lost!
I was not able to find in the Rust book a place where is cleared explained why the following code cannot compile:
struct X(i32);
fn main() {
let x: &X = &X(0);
let y = *x; // <-- Error here
}
I was expecting an error reported only if I tried to use x
after I moved its content in y
.
1 bis)
Similar question for Rc<T>
use std::rc::Rc;
#[derive(Debug)]
struct X(i32);
fn main() {
let x = Rc::new(X(0));
let y = *x; // <-- Error here
}
In this case I guess that is due to avoid that someone move the content bypassing the reference counter. So this is more understandable to me.
Deref
documentation states that deref
method (that is the operator *
as I understood) returns a value of type &Deref::Target
but if you check this little example it seems to return Deref::Target
. So actually operator *
does something more than just calling deref
method?
use std::ops::Deref;
struct X(i32);
impl Deref for X {
type Target = i32;
fn deref(&self) -> &i32 {
&self.0
}
}
fn main() {
let x = X(0);
let y: i32 = *x;
}
In the STD library it seems to me that Deref
trait is more used because of the deref coercions rule than the use of operator *
.
For example Vec<T>
give you an error if you try to use the operator directly on its instances, but it's used a lot to pass vector as slice (because of coercion). I found other cases, but now I am not able to remind them.
Deref coercions sometimes get me confuse. For example consider this little test:
use std::rc::Rc;
use std::cell::RefCell;
use std::cell::Ref;
#[derive(Debug)]
struct X(i32);
fn main() {
let x = Rc::new(RefCell::new(X(0)));
let y: Ref<X> = x.borrow(); // <-- This take &self that is coerced to RefCell
// I was expecting to call Rc::borrow (before checking its documentation)
// What if I want to call Rc::borrow?
}
How can I invoke the borrow
method on the Rc
instance and avoid the coercion?
Ok... I think it's enough for today!