Reputation: 764
I have this code (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
}
}
What I want to do is to keep the signature of give
function of the trait Trait
and at the same time to implement the trait Trait
for a the generic struct Struct
.
but I get this error
<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
^~~~~~
I thought to use what I saw in this question which matches an associated parameter with a generic parameter so I changed:
fn give<S>(&self, x: S) -> S
where S: Limit
to:
fn give<S = T>(&self, x: S) -> S
where S: Limit
I didn't get an error about this syntax but it wasn't the solution of the error above.
Is there any way to achieve what I want to do?
And a side question, what <S = T>
actually does in this case?
Upvotes: 2
Views: 645
Reputation: 65752
As you wrote it, your implementation of Trait
must implement give
in a way that works for any type that the caller wishes. On the other hand, your implementation of give
for Struct<T>
only works for a specific type, T
.
What about making the trait itself generic, rather than the method?
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
}
}
This way, an implementation of Trait<T>
only works for a specific T
type that is chosen by the implementor, not the caller.
Another option is to use associated types instead:
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
}
}
Here, Trait
is no longer generic, but Struct
remains generic, and each instance of Struct
implements the same Trait
trait.
Upvotes: 1