【问题标题】:How does Rust understand to call the appropriate implementation of from_iter using only FromIterator::from_iter?Rust 如何理解仅使用 FromIterator::from_iter 调用 from_iter 的适当实现?
【发布时间】:2019-01-07 09:39:59
【问题描述】:

如果集合实现了FromIterator,则可以使用Iterator trait 的collect 方法将迭代器转换为集合。

let vec = (0..10).collect::<Vec<_>>();
let devec = (0..10).collect::<VecDeque<_>>();

VecVecDeque 实现 FromIterator 特征。

Iterator::collect方法的实现是:

fn collect<B: FromIterator<Self::Item>>(self) -> B
where
    Self: Sized,
{
    FromIterator::from_iter(self)
}

Rust 如何理解从FromIterator::from_iter(self) 调用VecVecDequefrom_iter 方法?

【问题讨论】:

  • 你可以改写let vec: Vec&lt;_&gt; = (0..10).collect(),它以同样的方式推断类型(并且更符合IMO的习惯)

标签: rust traits


【解决方案1】:

FromIterator trait 有一个实现者时,它的形式为:

impl<T> FromIterator for Vec<T> {
    fn from_iter<I>(iter: I) -> Vec<T> { /* ... */ }
}

返回具体类型Self;这是collect 代码中的通用参数B

当您输入collect::&lt;Vec&lt;_&gt;&gt;() 时,您说BVec&lt;_&gt;,因此必须调用Vec&lt;_&gt;::from_iter()

collect 的实现可以写成:&lt;B as FromIterator&gt;::from_iter(self),但是更冗长。

【讨论】:

  • 谢谢。 ::from_iter(self) 达到了我正在寻找的点。
  • @nyinyithann 如果实现写成&lt;B as FromIterator&gt;::from_iter(self),Rust 不需要推断类型,因为它是明确给出的。如果您没有明确指定类型,Rust 需要根据它所拥有的信息来推断类型,我对您的问题的理解是您在询问 Rust 是如何执行类型推断的。这不是你的意思吗?
  • @SvenMarnach 不是特别关于类型推断。只是想知道 FromIterator::from_iter(self)。
  • @nyinyithann 好的,没关系,我误读了你的问题。我的回答可能对其他路过的人仍然有用,所以我会保留它。
  • @SvenMarnach 也感谢您的回答。得到一个指针来了解更多关于 Rust 的类型推断。
【解决方案2】:

让我们看一下FromIterator trait的定义:

pub trait FromIterator<A>: Sized {
    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}

FromIterator::from_iter()collect()方法的实现中如何使用,Rust知道FromIterator::from_iter()的调用将迭代器self作为参数,并返回一个B类型的对象。此信息与from_iter() 方法的定义相匹配,因此Rust 可以得出结论,FromIterator 特征实现的Self 类型必须是B,并且A 类型必须是项目类型迭代器。 FromIterator trait 的 Self 类型正是 Rust 需要调用 from_iter() 的类型。

类型推断如何工作的细节很复杂。 Rust 使用 Hindley-Milner 类型推理算法的变体。您可以在this document from the rustc guide 找到更多信息。

粗略地说,Rust 使用它所拥有的关于未知类型的所有信息作为约束,并迭代地改进其关于泛型类型的知识,直到每个未知类型只剩下一个类型,或者某些类型仍然模棱两可。在前一种情况下,类型推断成功并且所有类型都已推断出来,而在后一种情况下,Rust 会抛出一个错误,指出它需要进一步的类型注释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-22
    • 2022-12-07
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    相关资源
    最近更新 更多