考虑以下示例代码:
我将按照以下方式为
第一个问题是,由于
上述代码会导致编译错误:
好的,我们可以做一些妥协。让我们从DataRef中移除#[derive(Clone)]。(但是,在我的实际情况下,我无法这样做,因为它是一个破坏性的变化,没有意义)
如果我们按照定义实现
这显然是不可能的,因为我们无法在某处存储
#[derive(Clone)]
struct DataRef<'a> {
text: &'a str,
}
#[derive(Clone)]
struct DataOwned {
text: String,
}
我将按照以下方式为
DataRef
实现 ToOwned
:impl ToOwned for DataRef<'_> {
type Owned = DataOwned;
fn to_owned(&self) -> DataOwned {
DataOwned {
text: self.text.to_owned(),
}
}
}
从字面上讲,这很有道理,对吧?但是还存在一些问题。
第一个问题是,由于
ToOwned
提供了整体实现: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中移除#[derive(Clone)]。(但是,在我的实际情况下,我无法这样做,因为它是一个破坏性的变化,没有意义)
然后是第二个问题,ToOwned
的相关类型 Owned
要求 它实现了 Borrow<Self>
。
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功能)
borrow::ToOwned
与borrow:Cow<T>
密切相关,需要T: ToOwned
。对于Cow
,有PartialEq
、Ord
等的实现,这就是Borrow
要求的来源:因为Borrow
保证了拥有和借用变体的行为相同,所以Cow
可以将其自身进行比较和排序,无论值是借用还是拥有变体。Cow
之所以有效,是因为ToOwned
和Borrow
使得从一个变体无缝转换到另一个变体成为可能。您能详细说明一下为什么要实现ToOwned
吗? - user2722968