Rust 国际热核聚变实验堆和国际热核聚变实验堆有什么区别?

Rust 国际热核聚变实验堆和国际热核聚变实验堆有什么区别?,rust,Rust,我正在编写包含以下代码片段的教程: // Vec example let vec1 = vec![1, 2, 3]; let vec2 = vec![4, 5, 6]; // `iter()` for vecs yields `&i32`. Destructure to `i32`. println!("2 in vec1: {}", vec1.iter() .any(|&x| x == 2)); // `into_iter()` for vecs yields `i3

我正在编写包含以下代码片段的教程:

// Vec example
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];

// `iter()` for vecs yields `&i32`. Destructure to `i32`.
println!("2 in vec1: {}", vec1.iter()     .any(|&x| x == 2));
// `into_iter()` for vecs yields `i32`. No destructuring required.
println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2));

// Array example
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];

// `iter()` for arrays yields `&i32`.
println!("2 in array1: {}", array1.iter()     .any(|&x| x == 2));
// `into_iter()` for arrays unusually yields `&i32`.
println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2));
我完全搞糊涂了——对于
Vec
来说,从
iter
返回的迭代器产生引用,从
返回到iter
的迭代器产生值,但是对于数组,这些迭代器是相同的吗

这两种方法的用例/API是什么?

.into_iter()
不是为数组本身实现的,而是仅为
&[]
实现的。比较:

impl<'a, T> IntoIterator for &'a [T]
    type Item = &'a T

implTL;医生:

  • 返回到iter
    的迭代器可能会产生
    T
    &T
    &mut T
    中的任意一个,具体取决于上下文
  • 按照惯例,
    iter
    返回的迭代器将产生
    &T
  • 按照惯例,
    iter\u mut
    返回的迭代器将产生
    &mut T

第一个问题是:“iter的
是什么?”

into_iter
来自:

每种变体略有不同

这个函数直接使用
Vec
及其迭代器(
T
):

而这个,

impl;
fn into_iter(self)->slice::IterMutI(一个铁锈新手)从谷歌来到这里,寻求一个其他答案无法提供的简单答案。这是一个简单的答案:

  • iter()
    通过引用迭代项目
  • into_iter()
    迭代这些项,将它们移动到新范围中
  • iter_mut()
    迭代项目,为每个项目提供可变引用
因此,my|vec{…}
中x的
本质上等同于
my|vec.into_iter()。对于每个(|x|…)
-两者都
my|vec
的元素移动到
范围内

如果您只需要“查看”数据,请使用
iter
;如果您需要编辑/修改数据,请使用
iter\u mut
;如果您需要将数据赋予新的所有者,请使用
导入iter

这很有帮助:


将此设置为社区维基,以便如果我犯了任何错误,Rust pro可以编辑此答案。

我认为还有一些需要澄清的地方。集合类型,例如
Vec
VecDeque
,具有
到iter
方法中,该方法生成
T
,因为它们实现了
到迭代器中。没有什么可以阻止我们创建一个类型
Foo
,如果对它进行迭代,它将不会生成
T
,而是生成另一个类型
U
。也就是说,
Foo
实现了
IntoIterator

实际上,
std
中有一些例子:
&Path
IntoIterator
&UnixListener
IntoIterator


国际热核试验堆和国际热核试验堆之间的差异 回到原来的问题,即
到iter
iter
之间的区别。与其他人指出的类似,区别在于,
进入iter
是一种必需的方法,它可以产生中指定的任何类型。通常,如果一个类型在迭代器
中实现了
,按照惯例,它还有两个特别的方法:
iter
iter\u mut
,分别产生
&I
&mut I

这意味着我们可以创建一个函数,通过使用特征绑定来接收一个类型,该类型具有
到iter
方法(即,它是一个iterable):

fn process_iterable<I: IntoIterator>(iterable: I) {
    for item in iterable {
        // ...
    }
}
如果
v.iter()
等同于
&v
,因为两者都实现了
IntoIterator
,那么为什么Rust同时提供这两种功能呢?这是人体工程学的。在
for
循环中,使用
&v
v.iter()
更简洁;但在其他情况下,
v.iter()
(&v)清楚得多


何时向iter提供(实施)
和类型的
iter
方法 如果类型只有一种“方法”可以迭代,那么我们应该同时实现这两种方法。然而,如果有两种或两种以上的方法可以迭代,我们应该为每种方法提供一个特别的方法

例如,
String
既不向iter
提供
,也不向iter
提供
,因为迭代它有两种方法:以字节为单位迭代它的表示,或以字符为单位迭代它的表示。相反,它提供了两种方法:迭代字节和迭代字符,作为
iter
方法的替代方法



*从技术上讲,我们可以通过创造一种特质来做到这一点。但是我们需要为我们想要使用的每种类型
impl
这个特性。同时,
std
中的许多类型已经实现了
IntoIterator

IntoIterator
也实现了
&'a mut[T]
,因此它可以将对象移出数组。我认为这与以下事实有关:
IntoIter
返回结构没有生存期参数,而
Iter
mut
意味着可以更改值,而不是将其移出。@rodrigo
让mut a=[“abc.to_string()”;a、 进入| iter().map(|x |{*x})=>“错误:无法移出借用的内容”是的,我认为你是对的,不能从数组中移出值。但是,我仍然认为,作为库的一部分,应该可以使用不安全的Rust实现一种
ArrayIntoIter
struct。。。也许不值得,因为你无论如何都应该在这些情况下使用
Vec
。。。这就是为什么
array.into_iter
返回
&T
——因为自动将其转换为
&array.into_iter
——是这样的话,我不明白这与移动值或不移动值有什么关系。或者,正如@rodrigo所说,你之所以获得引用,仅仅是因为(出于某种原因)你无法移动值
pub trait IntoIterator 
where
    <Self::IntoIter as Iterator>::Item == Self::Item, 
{
    type Item;
    type IntoIter: Iterator;
    fn into_iter(self) -> Self::IntoIter;
}
impl<T> IntoIterator for Vec<T>
impl<'a, T> IntoIterator for &'a Vec<T>
impl<'a, T> IntoIterator for &'a mut Vec<T>
impl<T> IntoIterator for Vec<T> {
    type Item = T;
    type IntoIter = IntoIter<T>;

    fn into_iter(mut self) -> IntoIter<T> { /* ... */ }
}
impl<'a, T> IntoIterator for &'a Vec<T> {
    type Item = &'a T;
    type IntoIter = slice::Iter<'a, T>;

    fn into_iter(self) -> slice::Iter<'a, T> { /* ... */ }
}
impl<'a, T> IntoIterator for &'a mut Vec<T> {
    type Item = &'a mut T;
    type IntoIter = slice::IterMut<'a, T>;

    fn into_iter(self) -> slice::IterMut<'a, T> { /* ... */ }
}
fn process_iterable<I: IntoIterator>(iterable: I) {
    for item in iterable {
        // ...
    }
}
let v = vec![1, 2];

// Below is equivalent to: `for item in v.iter() {`
for item in &v {
    println!("{}", item);
}
let v = vec![1, 2];

let a: Vec<i32> = v.iter().map(|x| x * x).collect();
// Although above and below are equivalent, above is a lot clearer than below.
let b: Vec<i32> = (&v).into_iter().map(|x| x * x).collect();
let mut v = vec![1, 2];

// Below is equivalent to: `for item in v.iter_mut() {`
for item in &mut v {
    *item *= 2;
}