I see that std::convert::Into
has an implementation for anything that implements std::convert::From
:
impl<T, U> Into<U> for T where U: From<T>,
In the Rust 1.0 standard library, there are many implementations of From
while Into
is only implemented in 3 places. This makes it seem like implementing From
should be the default. I'm certain that there are times I would want to implement Into
and not From
, but I'm not seeing them.
The opposite of From . One should avoid implementing Into and implement From instead. Implementing From automatically provides one with an implementation of Into thanks to the blanket implementation in the standard library.
Trait std::convert::TryIntoAn attempted conversion that consumes self , which may or may not be expensive.
Implementing a trait in Rust To implement a trait, declare an impl block for the type you want to implement the trait for. The syntax is impl <trait> for <type> . You'll need to implement all the methods that don't have default implementations.
A trait in Rust is a group of methods that are defined for a particular type. Traits are an abstract definition of shared behavior amongst different types. So, in a way, traits are to Rust what interfaces are to Java or abstract classes are to C++. A trait method is able to access other methods within that trait.
TL;DR: prefer implementing From
.
Interestingly, the original RFC about the std::convert
traits suggested the opposite blanket implementation:
impl<T, U> From<T> for U where T: Into<U>
But on the PR implementing it, it was changed to the opposite:
Added
From
=>Into
implementation, which makes it possible to add conversions in both directions without running afoul of coherence. For example, we now haveFrom<[T]> for Vec<T>
whereT: Clone
, which yields the correspondingInto
going in the other direction -- despite the fact that the two types live in different crates.I also believe this addresses a few concerns about things implementing
From
instead ofInto
This last-moment change reflects that From
and Into
are basically equivalent. From
was chosen as the preferred one as it was less restrictive from the "type parameter vs. local type" point of view.
Before Rust 1.41.0, it wasn't possible to make a impl<'a, T> Into<Foo> for &'a [T]
, while impl<'a, T> From<&'a [T]> for Foo
was possible.
The first attempt raised a E0210
:
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) --> x.rs:3:10 | 3 | impl<'a, T> Into<Foo> for &'a [T] { | ^ type parameter `T` must be used as the type parameter for some local type | = note: only traits defined in the current crate can be implemented for a type parameter
In the standard library prior to Rust 1.14, there were only two examples of implementing Into
and not From
:
impl Into<Vec<u8>> for String
impl Into<OsString> for PathBuf
I think these are the reflexion of the logic of their interfaces. OsString
implements From<String>
and From<T> where T: AsRef<OsStr>
, because they are the natural things you'll want to build a OsString
from.
However, PathBuf
still implements Into<OsString>
as the reverse operation of its From<OsString>
implementation, but this logic belongs to PathBuf
, not OsString
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With