According to Rust Lang Programming Book, we know that:
The &self is actually short for self: &Self
However, from the example below (fn get_name), we wrote self: &Self, but self is not a reference but the object itself according to the error message. Why isn’t self a reference in this case? What is the ampersand for in &Self then?
Example: a simple struct with method that returns a person’s name
struct Person {
name: String
}
impl Person {
fn new(name: &str) -> Person {
Person {
name: name.to_string()
}
}
fn get_name(self: &Self) -> &String {
self.name // Error: expected `&std::string::String`, found struct `std::string::String`
}
}
>Solution :
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:
…
selfis not a reference but the object itself according to the error message. Why isn’tselfa 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.