考虑以下示例代码:
#[derive(Clone)]
struct DataRef<'a> {
text: &'a str,
}
#[derive(Clone)]
struct DataOwned {
text: String,
}
我将以这种方式实施ToOwned
换DataRef
:
impl ToOwned for DataRef<'_> {
type Owned = DataOwned;
fn to_owned(&self) -> DataOwned {
DataOwned {
text: self.text.to_owned(),
}
}
}
从字面上讲,这是有道理的,对吗?但也有一些问题.
第一个问题是,由于ToOwned
提供了blanket implementation:
impl<T> ToOwned for T where T: Clone { ... }
以上代码将给出一个编译错误:
error[E0119]: conflicting implementations of trait `std::borrow::ToOwned` for type `DataRef<'_>`
--> src/main.rs:13:1
|
13 | impl ToOwned for DataRef<'_> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `alloc`:
- impl<T> ToOwned for T
where T: Clone;
我们可以做出一些妥协.让我们从DataRef
中go 掉#[derive(Clone)]
.(然而,在我的真实 case 中,我不能这样做,因为这是一个突破性的改变,没有意义)
然后是第二个问题,它实现Borrow<Self>
的ToOwned
requires的相关类型Owned
.
pub trait ToOwned {
type Owned: Borrow<Self>;
fn to_owned(&self) -> Self::Owned;
...
}
如果我们按照定义为DataOwned
执行Borrow
:
impl<'a> Borrow<DataRef<'a>> for DataOwned {
fn borrow(&self) -> &DataRef<'a> {
DataRef { text: &self.text }
}
}
这显然是不可能的,因为我们无法在某处存储DataRef
.
所以我的问题是:
-
对于上面的例子,有没有办法实现
ToOwned
? -
考虑上述问题,
ToOwned
不应该由用户手动实现吗?因为我无法想象一个真实的例子来反对这一点. -
(可选答案)如果std
ToOwned
的定义允许更改,是否有任何可能的改进以使其更好?(允许存在不稳定和未实现的 rust 蚀特征)