【发布时间】:2016-11-03 01:42:02
【问题描述】:
我正在尝试创建一个包含isize 或AtomicIsize 的通用结构,但是当我尝试为结构的两种可能实现实现特征时遇到错误。我创建了一个最小的示例,在下面演示了我的问题。
use std::sync::atomic::{AtomicIsize, Ordering};
use std::ops::Deref;
use std::marker::PhantomData;
pub trait Counted {
fn inc(&self, value: isize);
}
pub type PlainCounter = isize;
pub type AtomicCounter = AtomicIsize;
pub struct Counter<'a, T: 'a> {
counter: T,
phantom: PhantomData<&'a T>,
}
impl<'a, T> Counter<'a, T>
where T: Deref<Target = PlainCounter>
{
pub fn new(counter: T) -> Self {
Counter {
counter: counter,
phantom: PhantomData,
}
}
}
impl<'a, T> Counted for Counter<'a, T>
where T: Deref<Target = PlainCounter>
{
fn inc(&self, value: isize) {
self.counter += 1;
}
}
impl<'a, T> Counter<'a, T>
where T: Deref<Target = AtomicCounter>
{
pub fn new(counter: T) -> Self {
Counter {
counter: counter,
phantom: PhantomData,
}
}
}
impl<'a, T> Counted for Counter<'a, T>
where T: Deref<Target = AtomicCounter>
{
fn inc(&self, value: isize) {
self.counter.fetch_add(value, Ordering::SeqCst);
}
}
我得到的错误是编译器找到了conflicting implementations of trait `Counted` for type `Counter<'_, _>`。似乎编译器无法确定实现是针对两种不同类型的T,即T: Deref<Target = PlainCounter> 和T: Deref<Target = AtomicCounter>。有没有办法向编译器提供额外的信息,以便它可以区分这两种情况,还是我完全走错了路?
【问题讨论】:
-
我认为您会遇到问题,因为您有两个
impls 看起来它们可以重叠,即使关联的类型阻止它实际发生。我可能会尝试为您的两种具体类型实现 {a, the} 特征,然后为Counter<T> where T: Counted和委托实现它。 -
@Shepmaster:我认为这是一个答案?
-
我很想看看你的意思的例子@Shepmaster - 我想我明白你的意思,但一个例子会很棒。
-
@Shepmaster 我采纳了您的建议并为
PlainCounter和AtomicCounter实施了Counted,然后实施了Counter<T> where T: Counted,其中Counter上的调用只是委托给它的counter字段和一切都很好。我对这个例子做了一些小的调整,让它更符合这个新方法,如果你有兴趣,例子是here。
标签: generics struct types rust