Shouldn't s.ptr point to the heap data, like s1.ptr too?
s references to the data but don't own the data.
In my understanding, reference in Rust is like reference in C++
without the pointer syntax. Is it correct?
len(&self) is a method of the String type. The &self parameter means that it needs a reference to the stack-allocated¹ String to operate, which in turn contains a pointer onto the heap where the characters are stored.
In this case, s contains a pointer to s1 within main's stack frame, and s1 contains a pointer onto the heap. Inside String::len(), selfalso contains a pointer into main's stack frame (referring to s1), and it derefetences that pointer to read the len field (which is completely different from the len() method, despite sharing a name).
¹ The method doesn't really care which part of memory the String is stored in, but it's on the stack in this example.
It is not. s has type reference-to-String, so it points to a string, which in turn points to a heap buffer. The image in the book is correct.
What might have confused you is the "ptr" in s. There are of course no fields in references – references aren't structs, they are pointers, so the ptr is not a field of the type &String itself; the pointer is the address of the value where the reference points (which happens to be th address of s1 in the example).
The s.len() syntax is just syntactic sugar for calling String::len(&s).
Your &s.len() isn't quite right because of precedence - you are calling s.len() and then taking a reference to the result (i.e. len2 is a &usize). I'm guessing you meant let len2 = (&s).len()?
I would say that they are "equivalent" and will give you the same result (by calling String::len() with a reference to a String).
The compiler may or may not generate some extra machine instructions in the second one because you are taking a reference - it really depends on the Rust compiler and LLVM's optimiser/code generator.
I’ll also add that it’s possible for a user-defined type to be written so that these two forms aren’t equivalent. It takes a bit of doing, though, and is usually a bad idea.