Because of automatic dereferencing.
C has the .
and ->
operators, where .
is applied to values and ->
to pointers. In C, x->y
is exactly equivalent to (*x).y
.
Rust has .
but not ->
, so to make the syntax friendly, .
will usually automatically dereference when the compiler cannot find the member requested. In this case, &Person
doesn't have a name
attribute (since references can't have attributes), so the compiler tries again with a dereference ((*self).name
) and it finds the attribute this time, on Person
.
Since *self
has type Person
, (*self).name
has type String
. To fix the problem, you take a reference to the string by doing &self.name
, which means the same thing as &((*self).name)
(extra parens added for clarity).
To directly address your question:
... self
is not a reference but the object itself according to the error message. Why isn't self
a reference in this case?
The error message only refers to the String
attribute and doesn't really give you any information about self
at all. self
is indeed a reference. If you throw this in your impl Person
:
fn test(&self) { self }
Then the compiler will tell you what self
is (because it doesn't match the implied ()
return type):
error[E0308]: mismatched types
--> src/lib.rs:12:18
|
12 | fn test(&self) { self }
| - ^^^^ expected `()`, found `&Person`
| |
| expected `()` because of default return type
Note that you will see the same compiler error if you say fn get_name(&self)
. This error isn't caused by the self: &Self
syntax; it is indeed equivalent to &self
.