I need some help understanding the "Where’s the ->
Operator?" of Chapter 5.3 (emphasis added):
Where’s the
->
Operator?In C and C++, two different operators are used for calling methods: you use
.
if you’re calling a method on the object directly and->
if you’re calling the method on a pointer to the object and need to dereference the pointer first. In other words, ifobject
is a pointer,object->something()
is similar to(*object).something()
.Rust doesn’t have an equivalent to the
->
operator; instead, Rust has a feature called automatic referencing and dereferencing. Calling methods is one of the few places in Rust that has this behavior.Here’s how it works: when you call a method with
object.something()
, Rust automatically adds in&
,&mut
, or*
soobject
matches the signature of the method. In other words, the following are the same:p1.distance(&p2); (&p1).distance(&p2);
The first one looks much cleaner. This automatic referencing behavior works because methods have a clear receiver—the type of
self
. Given the receiver and name of a method, Rust can figure out definitively whether the method is reading (&self
), mutating (&mut self
), or consuming (self
). The fact that Rust makes borrowing implicit for method receivers is a big part of making ownership ergonomic in practice.
I'm not sure I understand the example with p1
.
- Is it just showing that the semanitcs of
.
applied to an object are the same as those of.
applied to a reference to that object? So, assumingdistance()
borrowsself
immutably andp1
is of typeT
, then is this example showing thatp1.distance(&p2)
is equivalent toT::distance(&p1, &p2)
(where thep1
is first transformed to&p1
via automatic referencing)?
Also, regarding the last two lines of the quoted excerpt:
- I don't understand the meaning of "clear receiver". Why isn't automatic referencing and dereferencing enabled for regular functions? In what way do they not have a clear receiver?
- What does "making ownership ergonomic" mean?