Reputation: 16168
I want to write a function that accepts Iterator
of type that has ToString
trait.
What I have in mind:
fn parse<T: Iterator /* ?T::Item : ToString? */>(mut args: T) -> Result<String, String> {
match args.next() {
Some(x) => x.to_string(),
None => String::from("Missing parameter"),
}
}
Upvotes: 18
Views: 17433
Reputation: 154911
As of Rust 1.79, you can place the bound directly on the associated Item
type, so you can define parse()
like this:
fn parse<T: Iterator<Item: ToString>>(mut args: T) -> Result<String, String> {
...
}
or even like this:
fn parse(mut args: impl Iterator<Item: ToString>) -> Result<String, String> {
...
}
Upvotes: 0
Reputation: 70673
You can use the Item =
syntax:
fn parse<I: ToString, T: Iterator<Item = I>>(mut args: T) -> Result<String, String>
That allows you to simplify this further with the impl
syntax:
fn parse<T: Iterator<Item = impl ToString>>(mut args: T) -> Result<String, String>
and finally:
fn parse(mut args: impl Iterator<Item = impl ToString>) -> Result<String, String>
I would consider this a more readable alternative.
Upvotes: 15
Reputation: 58735
Yes, you can do that with a where
clause:
fn parse<T: Iterator>(mut args: T) -> Result<String, String>
where
<T as Iterator>::Item: ToString,
{
// ....
}
Or, since it's unambiguous which Item
is meant here, the bound can just be:
where T::Item: ToString
Upvotes: 24