我想实施Borrow
for UserFriendlyDataStructure
提供对internal_data
函数内的字段应该与数据提供者无关。的类型internal_data
字段由与特征相关的类型决定TraitA
。请注意,Sealed
特征确保这里的这些特征都不能被其他板条箱实现;这是我严格提供的功能。此外,类型TraitA::Data
受到空特征的限制DataTrait
阻止UserFriendlyDataStructure
以免被用作该类型。
下面的例子解释得最好:
use std::borrow::Borrow;
use std::marker::PhantomData;
mod private {
pub trait Sealed {}
}
pub trait DataTrait: private::Sealed {}
pub trait TraitA: private::Sealed {
type Data: DataTrait;
}
pub struct UserFriendlyDataStructure<A: TraitA> {
internal_data: A::Data,
_a: PhantomData<A>,
}
impl<A: TraitA> Borrow<A::Data> for UserFriendlyDataStructure<A> {
fn borrow(&self) -> &A::Data {
&self.internal_data
}
}
pub fn important_function<A: TraitA, T: Borrow<A::Data>>(data: &T) {
let _internal_data = data.borrow();
// Do lots of work.
}
#[cfg(test)]
mod tests {
use super::*;
pub struct TestData(u32);
impl super::private::Sealed for TestData {}
impl DataTrait for TestData {}
pub struct TestProvider;
impl super::private::Sealed for TestProvider {}
impl TraitA for TestProvider {
type Data = TestData;
}
#[test]
fn basic_test() {
let ufds: UserFriendlyDataStructure<TestProvider> = UserFriendlyDataStructure {
internal_data: TestData(100),
_a: PhantomData::default(),
};
important_function::<TestProvider, _>(&ufds);
}
}
不幸的是,编译器抱怨:
error[E0119]: conflicting implementations of trait `std::borrow::Borrow<UserFriendlyDataStructure<_>>` for type `UserFriendlyDataStructure<_>`:
--> src/lib.rs:19:1
|
19 | impl<A: TraitA> Borrow<A::Data> for UserFriendlyDataStructure<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> std::borrow::Borrow<T> for T
where T: ?Sized;
有办法实现我想做的事情吗?
可以通过引入冗余的第二类型参数来诱使编译器接受代码,该参数被限制为与A::Data
:
impl<A, D> Borrow<D> for UserFriendlyDataStructure<A>
where
A: TraitA<Data = D>,
D: DataTrait,
{
fn borrow(&self) -> &A::Data {
&self.internal_data
}
}
我不知道为什么会这样,只是限制A::Data: DataTrait
没有。我认为编译器应该接受这两个版本。
()
Edit:事实上我们需要冗余类型D
上面的代码似乎是当前编译器实现的缺点 https://github.com/rust-lang/rust/issues/50237,并有望在实验型推理机得到解决chalk https://github.com/rust-lang-nursery/chalk被集成到编译器中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)