C++ has splitting method overloading, Rust has joining method overloading. In other mainstream languages it is common to overload a method name from one type to others. This, I call, "splitting polymorphism". Rust does not permit splitting polymorphism for one reason or another. Instead Rust encourages methods to be overloaded from other types to one. This, I call, "joining polymorphism". A simple example that is very handy according to the Rust library is using the Into trait to join the str and String types. It can be fairly annoying to deal with these two string types on top of the indirection of what is or is not and how many references that have been attached to the ground type.
Conveniently, the From<&str> type, which implements Into
let my_string: String = my_str.into;
In general to use joining polymorphism you will implement a trait that induces a type collision on the right hand side of its type signature. Often this right hand side collision will be slightly obscured by a definition that uses the Self type. Do not let this confuse you, not all trait definitions are made equal. For reference, here is an Into implementation from the Rust documentation:
;
In the above code notice that any trait that also returns a Vec
It is also possible to go the other way from a String to a str by using a separate trait than From and Into. The Deref trait provides the opportunity for a similar type coercion when referencing one type to coerce the type into another type. This is most commonly seen in practical use to go from a String reference to a str reference:
...
foo
In the above code, the String my_string is implicitly converted to a str. This implementation also does not require a copy or clone, so it is thought to be less expensive than the Into