将通用参数与impl的另一个泛型参数匹配

时间:2015-09-04 23:23:46

标签: generics rust traits

我有这段代码(in playground):

trait Limit {}

pub trait Trait
{
    fn give<T>(&self, x: T) -> T
    where T: Limit;
}

struct Struct<T: Limit> {field: T}

impl<T> Trait for Struct<T>
    where T: Limit
{   
    fn give<S>(&self, x: S) -> S 
    where S: Limit
    {
       self.field
       //interacts with x parameter and gives an "S: Limit" result       
    }
} 

我想要做的是保留特征{{​​1}}的{​​{1}}函数的签名,同时为通用结构{{1}实现特征give }}

但我收到此错误

Trait

我想使用我在question中看到的与相关参数匹配的通用参数,所以我改变了:

Trait

为:

Struct

我没有收到有关此语法的错误,但它并不是上述错误的解决方案。

有没有办法实现我想做的事情?

还有一个问题,<anon>:17:8: 17:14 error: mismatched types: expected `S`, found `T` (expected type parameter, found a different type parameter) [E0308] <anon>:17 self.field ^~~~~~ 在这种情况下实际做了什么?

1 个答案:

答案 0 :(得分:1)

正如您所写,Trait的实现必须以适用于调用者所希望的任何类型的方式实现give。另一方面,give Struct<T>的实施仅适用于特定的类型T

如何让特质本身变成通用的,而不是方法?

pub trait Trait<T> where T: Limit {
    fn give(&self, x: T) -> T;
}

impl<T> Trait<T> for Struct<T> where T: Limit {   
    fn give(&self, x: T) -> T 
    {
       self.field // does not compile, you can't give away one of your fields
                  // unless you mem::replace() it with another value
    }
} 

这样,Trait<T>的实现仅适用于实现者选择的特定T类型,而非调用者。

另一种选择是改为使用相关类型:

pub trait Trait {
    type T: Limit;

    fn give(&self, x: Self::T) -> Self::T;
}

impl<T> Trait for Struct<T> where T: Limit {
    type T = T;

    fn give(&self, x: T) -> T 
    {
       self.field
    }
} 

此处,Trait不再是通用的,但Struct仍然是通用的,Struct的每个实例都实现相同的Trait特征。