考虑以下示例代码:
#[derive(Clone)]
struct DataRef<'a> {
text: &'a str,
}
#[derive(Clone)]
struct DataOwned {
text: String,
}
我要实施ToOwned
for DataRef
这样:
impl ToOwned for DataRef<'_> {
type Owned = DataOwned;
fn to_owned(&self) -> DataOwned {
DataOwned {
text: self.text.to_owned(),
}
}
}
从字面上看,这句话有道理吧?但也存在一些问题。
第一个问题是,因为ToOwned
提供了一个一揽子实施 https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#implementors:
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;
好吧,我们可以做出一些妥协。让我们删除#[derive(Clone)]
from DataRef
。 (但是,在我的实际情况中我不能这样做,因为这是一个破坏性的改变并且没有意义)
然后是第二个问题,关联类型Owned
of ToOwned
requires https://doc.rust-lang.org/std/borrow/trait.ToOwned.html它实现了Borrow<Self> https://doc.rust-lang.org/std/borrow/trait.Borrow.html.
pub trait ToOwned {
type Owned: Borrow<Self>;
fn to_owned(&self) -> Self::Owned;
...
}
如果我们实施Borrow
for DataOwned
正如其定义:
impl<'a> Borrow<DataRef<'a>> for DataOwned {
fn borrow(&self) -> &DataRef<'a> {
DataRef { text: &self.text }
}
}
这显然是不可能的,因为我们无法存储DataRef
某处。
所以我的问题是: