gpt4 book ai didi

rust - 在使用关联类型的情况下,如何为通用容器实现借用?

转载 作者:行者123 更新时间:2023-11-29 07:54:50 26 4
gpt4 key购买 nike

我想为 UserFriendlyDataStructure 实现 Borrow 以提供对函数内的 internal_data 字段的访问,该函数应该与数据提供者。 internal_data 字段的类型由与特征 TraitA 关联的类型确定。请注意,Sealed 特性确保这里的这些特性都不能被其他 crate 实现;这是我严格提供的功能。此外,类型 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 行不通。我认为编译器应该接受这两个版本。

( Full code on the playground )

编辑:我们在上面的代码中需要冗余类型 D 的事实似乎是 shortcoming of the current compiler implementation ,并有望在实验型推理引擎中得到解决 chalk被集成到编译器中。

关于rust - 在使用关联类型的情况下,如何为通用容器实现借用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53021939/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com