I'm new to Rust and trying to learn how references work. In the following code when I want to do a calculation on a1
which is i32
I don't have to dereference it. But with b1
which is a Box
, I have to dereference it.
Actually both let a2 = a1 * 2;
and let a3 = *a1 * 2;
behave similarly. It looks like dereferencing in primitives is optional OR the compiler is implicitly doing that for us.
fn main(){
let a = 5;
let b = Box::new(10);
let a1 = &a;
let b1 = &b;
println!("{} {}", a1, b1);
let a2 = a1 * 2;
let b2 = (**b1) * 10;
let a3 = *a1 * 2;
println!("{} {} {}", a2, a3, b2);
}
Can someone please explain this functionality?
Rust will also insert automatic dereferencing as part of deref coercion. This is a special coercion that can only convert from one reference type to another.
The dereference operator is also known as the indirection operator. Simply put, the dereferencing operator allows us to get the value stored in the memory address of a pointer. In Rust, we use the Deref trait to customize the behaviour of the dereferencing operator.
The Rust language has a number of types that are considered 'primitive'. This means that they're built-in to the language. Rust is structured in such a way that the standard library also provides a number of useful types built on top of these ones, as well, but these are the most primitive.
It’s simply impossible to dereference a reference in Rust (unless a is Copy ): let a = String::from ("hello"); let b = &a; let c = *b; // Error! I think dereferencing acutally isn’t the opposite of referencing in Rust. The opposite of referencing is dropping a reference, and the deref operator is totally unrelated to the ref operator.
In some ways Rust's references resemble pointers in C++. For example, the & and * operators are very similar in the two languages. But these syntactical similarities are superficial. C++ pointers (even smart pointers) can't match Rust references' safety. References in C++, in contrast, are quite dissimilar to Rust references, even syntactically.
Bookmark this question. Show activity on this post. I'm learning/experimenting with Rust, and in all the elegance that I find in this language, there is one peculiarity that baffles me and seems totally out of place. Rust automatically dereferences pointers when making method calls.
There can be only one mutable reference at a time. The code above tries to create two mutable references to the same data. If we try to compile this code, Rust will emit this error: While it may occur unexpected, it actually makes perfect sense.
All of the arithmetic operators in Rust are implemented for both primitive values and references to primitives on either side of the operator. For example, see the Implementors
section of std::ops::Mul
, the trait that controls the overriding of the *
operator.
You'll see something like:
impl Mul<i32> for i32
impl<'a> Mul<i32> for &'a i32
impl<'a> Mul<&'a i32> for i32
impl<'a, 'b> Mul<&'a i32> for &'b i32
and so on and so on.
In your example, b1
has a type of &Box<i32>
(the default integer type), and while Box
implements many traits as a passthrough for its contained type (e.g. impl<T: Read> Read for Box<T>
), the arithmetic operators are not among them. That is why you have to dereference the box.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With