References and the dot operator
We learned that when you have a reference, you need to use *
to get to the value. A reference is a different type, so this won't work:
fn main() { let my_number = 9; let reference = &my_number; println!("{}", my_number == reference); // ⚠️ }
The compiler prints:
error[E0277]: can't compare `{integer}` with `&{integer}`
--> src\main.rs:5:30
|
5 | println!("{}", my_number == reference);
| ^^ no implementation for `{integer} == &{integer}`
So we change line 5 to println!("{}", my_number == *reference);
and now it prints true
because it's now i32
== i32
, not i32
== &i32
. This is called dereferencing.
But when you use a method, Rust will dereference for you. The .
in a method is called the dot operator, and it does dereferencing for free.
First, let's make a struct with one u8
field. Then we will make a reference to it and try to compare. It will not work:
struct Item { number: u8, } fn main() { let item = Item { number: 8, }; let reference_number = &item.number; // reference number type is &u8 println!("{}", reference_number == 8); // ⚠️ &u8 and u8 cannot be compared }
To make it work, we need to dereference: println!("{}", *reference_number == 8);
.
But with the dot operator, we don't need *
. For example:
struct Item { number: u8, } fn main() { let item = Item { number: 8, }; let reference_item = &item; println!("{}", reference_item.number == 8); // we don't need to write *reference_item.number }
Now let's create a method for Item
that compares number
to another number. We don't need to use *
anywhere:
struct Item { number: u8, } impl Item { fn compare_number(&self, other_number: u8) { // takes a reference to self println!("Are {} and {} equal? {}", self.number, other_number, self.number == other_number); // We don't need to write *self.number } } fn main() { let item = Item { number: 8, }; let reference_item = &item; // This is type &Item let reference_item_two = &reference_item; // This is type &&Item item.compare_number(8); // the method works reference_item.compare_number(8); // it works here too reference_item_two.compare_number(8); // and here }
So just remember: when you use the .
operator, you don't need to worry about *
.