Say I have this function:
fn map_add<I>(lane: I) -> impl Iterator<Item = u8>
where
I: IntoIterator<Item = u8>,
{
lane.into_iter().map(|v| v + 1)
}
Why do I not have to specify the associated type?
<I as IntoIterator>::IntoIter
Say I have this function:
fn map_add<I>(lane: I) -> impl Iterator<Item = u8>
where
I: IntoIterator<Item = u8>,
{
lane.into_iter().map(|v| v + 1)
}
Why do I not have to specify the associated type?
<I as IntoIterator>::IntoIter
You can omit them whenever you don't need to constrain the associated type for the purposes of your function body. For example, this function works with any IntoIter
and any Item
, so the where
clause can be simple:
fn collect_vec<I>(it: I) -> Vec<I::Item>
where
I: IntoIterator,
{
it.into_iter().collect()
}
Your map_add
function body requires I::Item = u8
(or another integer type), but it doesn't impose any requirements on I::IntoIter
. You could certainly specify some additional constraint like
where I: IntoIterator<
Item = u8,
+ IntoIter = std::vec::IntoIter<u8>,
>,
But you only have to specify the constraints that enable your function body to compile.
Associated types are outputs of implementations as well -- if you know the implementation, the associated types are uniquely determined. You don't need to specify the associated type to determine the implementation.
The implementation is uniquely determined by its inputs -- the implementing type and any generic parameters on the trait itself.
Ah, makes sense. I think I was wrapped around the axle with a compile error that I took the wrong impression from.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.