I'm new to Rust and I don't understand the following piece of code:
let mut x = 5; { let y = &mut x; *y += 1; } println!("{}", x);
Explanation from the Rust site:
You'll also notice we added an asterisk (
*
) in front ofy
, making it*y
, this is becausey
is a&mut
reference. You'll need to use astrisks [sic] to access the contents of a reference as well.
If *y
is a reference, why does the following code work
fn main() { let mut x = 5; { let y = &mut x; println!("{}", y); } }
I know I'm not modifying the value here, but what is the difference and why would y += 1;
not work?
It dereferences num so you assign to the place in memory it points into (the num variable in main() ) and not to the num variable.
Please review Appendix B: Operators and Symbols of The Rust Programming Language. In this case, the double colon ( :: ) is the path separator. Paths are comprised of crates, modules, and items. The full path for your example item, updated for 1.0 is: std::usize::BITS.
The dereference operator When applied to a pointer it denotes the pointed-to location. If the expression is of type &mut T or *mut T , and is either a local variable, a (nested) field of a local variable or is a mutable place expression, then the resulting memory location can be assigned to.
If
*y
is a reference
*y
is not a reference. y
is a reference; *y
dereferences y
, allowing you access to the referred-to value.
what is the difference [between
+=
andprintln!
]
println!
is a macro that automatically references the arguments given to it. In addition, the Display
trait (used via {}
in the format string) is implemented for all references to types that themselves implement Display
(impl<'a, T> Display for &'a T where T: Display + ?Sized
).
Thus, println!("{}", y);
is actually printing out a reference to a reference to a value. Those intermediate references are automatically dereferenced due to the implementation of Display
.
+=
, on the other hand, is implemented via the AddAssign
trait. The standard library only implements adding an integer type to itself (impl AddAssign<i32> for i32
). That means that you have to add an appropriate level of dereferencing in order to get both sides to an integer.
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