Why is Deref
a supertrait of IntoOwned
On IRLO, there was some reservation in regard to the idea of making IntoOwned: Deref
. I'd like to give a short explanation why I think it should be:
IntoOwned
is not a generic conversion from a type into an owned type. IntoOwned
should be more understood as RefIntoOwned
or RefWhichManagesOwnershipIntoOwned
. These reference-like types are:
-
&'a T
(always borrowed) -
Cow<'a, T>
(sometimes borrowed, sometimes owned, determined at run-time) -
Owned<T>
(always owned)
IntoOwned
can still be used to go from some non-owned type like str
to String
. This is because IntoOwned
is implemented for &str
:
use std::borrow::{Borrow, Cow};
use std::ops::Deref;
pub trait IntoOwned: Sized + Deref {
type Owned: Borrow<<Self as Deref>::Target>;
fn into_owned(self) -> Self::Owned;
}
impl<'a, T> IntoOwned for &'a T
where
T: ?Sized + ToOwned,
{
type Owned = <T as ToOwned>::Owned;
fn into_owned(self) -> Self::Owned {
self.to_owned()
}
}
fn main() {
let hello: &str = "Hello World!";
let owned: String = hello.into_owned();
println!("{owned}");
let cow_borrowed: Cow<'static, str> = Cow::Borrowed("I'm a cow.");
let my_own_cow: String = cow_borrowed.into_owned();
println!("{my_own_cow}");
}
Output:
Hello World!
I'm a cow.
Oooops… in the above Playground I accidentally used Cow::into_owned
, which is also a method of the enum (not a trait method) having the same name and doing the same in that case. But it works as trait method of IntoOwned
as well, see fixed Playground.