Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust .next()后面的for。zip():防止移动迭代器_Rust - Fatal编程技术网

Rust .next()后面的for。zip():防止移动迭代器

Rust .next()后面的for。zip():防止移动迭代器,rust,Rust,我刚开始生锈,还没有完全弄明白这一切。我一直在读很多书,也在玩数学题。我用这个签名写了一个函数: pub fn prime_factors(n: u64) -> Vec<u64> { 其中一个亮点是,我正在将静态数组与向量进行比较(出于学习目的,这是当前需要的,因为我想练习泛型) 我的测试功能是我实际遇到问题的功能。要进行测试,函数必须遍历两个集合,检查每个索引是否相等。我使用.zip()来实现这一点,但是如果集合不均匀,迭代器将只遍历较短集合的索引。所以在zip之后,我想检

我刚开始生锈,还没有完全弄明白这一切。我一直在读很多书,也在玩数学题。我用这个签名写了一个函数:

pub fn prime_factors(n: u64) -> Vec<u64> {
其中一个亮点是,我正在将静态数组与向量进行比较(出于学习目的,这是当前需要的,因为我想练习泛型)

我的测试功能是我实际遇到问题的功能。要进行测试,函数必须遍历两个集合,检查每个索引是否相等。我使用
.zip()
来实现这一点,但是如果集合不均匀,迭代器将只遍历较短集合的索引。所以在
zip
之后,我想检查迭代器中是否有额外的元素

以下内容未编译:

fn assert_list_eq<I, T>(mut expected: I, mut actual: I)
    where I: Iterator<Item=T> + Clone,
          T: PartialEq + Debug {
    for (e, a) in expected.zip(actual) {
        assert_eq!(e, a);
    }
    // fail if there are any "leftovers"
    assert_eq!(None, expected.next());
    assert_eq!(None, actual.next());
}

顺便说一句(承认XY问题):我很高兴了解一个内置断言来比较两个有序集合,但这并不是我真正感到困惑的地方。

按值获取其参数,因此它们会被移动,以后不能使用它们

但是,有一个解决方法:有一个方法返回对迭代器的可变引用,诀窍是
&muti,其中I:iterator
还实现了
迭代器。因此,在将两个迭代器传递到
zip()之前,您可以将
.by_ref()
应用于这两个迭代器:

[…]
使用trait(
RangeFull
的缩写)强制将表达式转换为切片

另一种方法是交换操作数,这样就不需要
[…]

#[test]
fn prime_factors_test() {
    assert_eq!(prime_factors(30), [2,3,5]);
}

这是因为标准库为Vec提供了
impl PartialEq
,但没有为[T;3]
提供
impl PartialEq

。此外,如果您确实想比较迭代器而不是切片,那么标准库和Itertools中都有。
fn assert_list_eq<I, T>(expected: I, actual: I)
    where I: Iterator<Item=T> + Clone,
          T: PartialEq + Debug {
    assert!(expected.clone().count() == actual.clone().count()); // desperation
    for (e, a) in expected.zip(actual) {
        assert_eq!(e, a);
    }
}
fn assert_list_eq<I, T>(mut expected: I, mut actual: I)
    where I: Iterator<Item=T> + Clone,
          T: PartialEq + Debug {
    for (e, a) in expected.by_ref().zip(actual.by_ref()) {
        assert_eq!(e, a);
    }
    // fail if there are any "leftovers"
    assert_eq!(None, expected.next());
    assert_eq!(None, actual.next());
}
#[test]
fn prime_factors_test() {
    assert_eq!([2,3,5][..], prime_factors(30)[..]);
}
#[test]
fn prime_factors_test() {
    assert_eq!(prime_factors(30), [2,3,5]);
}