Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Rust: Why isn't "self" a reference when "self: &Self"?

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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:

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading