&self
in fn as_ref(&self)
is actually shorthand for: fn as_ref(self: &Self)
. It does not create a reference; it merely requires one to be passed to the function.
match
doesn't need *self
. It can also be written like so:
match self {
&Some(ref x) => Some(x),
&None => None,
}
They are broadly equivalent. The reason one or the other is needed is that self
is of type &Self
, and the match
has to reflect that. You must either dereference the &Self
to get a Self
, then match on that or match on &Self
and have that reflected in the patterns being used.
v.push(5)
won't work in that example because Vec::push
requires &mut self
, but you have an immutable pointer.
So it would need to be:
fn foo(v: &mut Vec<i32>) { v.push(5); }
Now, that works because it's equivalent to Vec::push(v, 5);
which matches the argument types exactly.
In Java a reference just likes an alias of an object, why Rust need a '*'. What's the difference between the two 'reference'?
Because Rust cares about the difference, Java doesn't. Java has only one kind of reference; Rust has (off the top of my head):
&T
&mut T
*const T
*mut T
Box<T>
Rc<T>
Arc<T>
Unique<T>
(technically still an unstable implementation detail, though)
Also, Java doesn't simply not require *
on pointers, it wouldn't make any sense at all. You can't dereference a pointer in Java because there's no way to know the size of the thing behind the pointer.
It's broadly the same as the reason as why Rust doesn't allow you to use dynamically sized types as values, but that's tangential.
Dose the ref x in the match branch mean let x = &x ?
No; x
doesn't exist prior to this.
ref x
in Some(ref x)
as a pattern is saying "bind to the value in this position by immutable reference to the name x
". In this case, Self
is actually Option<T>
; thus, the interior of Some
is a value of type T
. Binding to this interior by reference means that x
is of type &T
; hence, wrapping it in Some
again produces an Option<&T>
, which is what gets returned.