为什么IntoIterator trait需要显式指定关联类型Item?

4
自从IntoIterator特性的关联类型IntoIter实现了Iterator特性,那么难道不足以推断出关联类型Item吗?

1
@L.F. OP问为什么IntoIterator有一个type Item,当这个信息可以从type IntoIter中获得。 - vallentin
@vallentin 抱歉,我没有意识到它是指IntoIter关联类型。 - L. F.
1个回答

8
为什么 IntoIterator trait 要求显式的 type Item 声明?
实际上并不需要。当你实现 IntoIterator for ... 时,Item 是多余的,可以通过 IntoIter 获得。
这是在 PR#22313中介绍的。简而言之,引入它的原因是为了简化where语句。如果必须指定IntoIter,那么很快就会变得繁琐。
where I: IntoIterator<IntoIter = ...>

在这种情况下,做起来要容易得多:
where I: IntoIterator<Item = ...>

让我们考虑一个随机的例子,比如 print_strings。在此之前,你需要像这样做:

fn print_strings<I, T>(iter: I)
where
    I: IntoIterator<IntoIter = T>,
    T: Iterator<Item = &'static str>,
{
    for s in iter {
        println!("{}", s);
    }
}

而现在可以简化为:

fn print_strings<I>(iter: I)
where
    I: IntoIterator<Item = &'static str>,
{
    for s in iter {
        println!("{}", s);
    }
}

fn main() {
    print_strings(vec!["foo", "bar", "baz"]);
}

嗯,我不认为你答案的第一部分是正确的,因为当实现IntoIterator特性时,你确实需要type Item声明,尽管它是多余的,因为它与<Self::IntoIter as Iterator>::Item是相同的。(至少在关联类型默认值稳定之前不是可选的。)在特性约束中是不需要的,当然,这对于任何关联类型都是如此,无论多余与否。 - Frxstrem
1
我所说的“冗余”,是指在以前实现IntoIterator时不需要type Item,而现在当然需要了。我的意思是,它的引入并不是因为IntoIterator本身存在问题,而是为了简化where子句。 :) - vallentin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接