Reputation: 3196
I'd like to create a trait
that forces the return type of Result<T, E>
on some functions, but I cannot figure out the syntax to define this.
I've gotten as far as:
pub type NamedResult<T, E> = Result<T, E>;
pub trait Foo {
fn bar<T, E>(&self) -> NamedResult<T, E>;
}
pub struct Thing;
impl Foo for Thing {
pub fn bar<T, E>(&self) -> NamedResult<T, E> {
Ok(78i32)
}
}
Produces the following error:
error: mismatched types:
expected 'T',
found 'i32'
(expected type parameter, found i32) [E0308]
So I then tried:
pub fn bar<i32, String>(&self) -> NamedResult<i32, String> {
Ok(78i32)
}
And received the following error:
error: user-defined types or type parameters cannot shadow the primitive types [E0317]
What would the proper syntax be so that I can force the implementer of said trait to return a Result<T, E>
type on certain functions?
Upvotes: 7
Views: 11318
Reputation: 90752
fn bar<T, E>(&self) -> Result<T, E>;
This says that you have a function bar
which, given arbitrary types T
and E
, will return a Result<T, E>
. Remember that: the user specifies the type. But what the body of your method is doing is returning a Result<i32, _>
, but i32
is not T
.
If you wish to specify the type that will be returned, that needs to be specified on the trait implementation, either as a generic or (more normally) as an associated type:
pub trait Foo {
type Bar;
type BarError;
fn bar(&self) -> Result<Self::Bar, Self::BarError>;
}
pub struct Thing;
impl Foo for Thing {
type Bar = i32;
type BarError = ();
pub fn bar(&self) -> Result<i32, ()> {
Ok(78i32)
}
}
This way, the user is not specifying the type; rather, when you know that you are calling the bar
method on a Thing
, you know that the output type will be Result<i32, ()>
.
Upvotes: 8