...
Step-by-step, how to understand the describe() function example
(assuming I understand this, which is an if, a small if, but an if)
Part A - We can implement methods directly on shared references themselves. There is no dereferencing then (playground)
In a sense then the method implemented, when called on a shared reference, takes ownership of the shared reference, per se, not the value the shared reference points to.
Code Block | ||
---|---|---|
| ||
use std::borrow::Cow;
trait CustomInto<T> {
fn custom_into(self) -> T;
}
impl<'a> CustomInto<Cow<'a, str>> for &'a str {
fn custom_into(self) -> Cow<'a, str> {
Cow::Borrowed(self)
}
}
fn main(){
let _cow = "hello there".custom_into();
} |
Part B -
Consider two traits
From<String>
From<&'a str>
Cow<'a, str> implements both traits
Cow has the associated function
fn from(s: String) → Cow<'a, str>
Cow has another associated function
fn from(s: &'a str) → Cow<'a, str>
Therefore String implements<
Consider the additional trait
Into<Into<Cow<'a, Cow<'a str>>
String automatically implements Into, as does str, given that the From traits are implemented
Both String and str implement Into with a method of the following form
fn into(self) → Cow<a', str>
In the first four arms of the match expression, there are string literals upon which the method into() is called. We know the methods must have a return type of Cow<'static, str>.
A string literal is of type &str, a shared reference to a string slice.
When applying the method into(), the string literal is dereferenced into a string slice str
Then the method into() can be applied on the str. We have already seen that this method exists.