是否从&;str;数组中获取迭代器<;item=str&>? [英] Getting an Iterator<Item=str> from an array of &str?
问题描述
我正在尝试抽象一个函数,以获取std::str::Lines
的实例和从&str
的数组中创建的模拟版本,用于测试目的。
我的代码(确实有效)如下所示:
use std::fs;
#[test]
fn test_day_1() {
let v = ["3", "3", "4", "-2", "-4"].iter().map(|x| *x);
assert_eq!(day1(v), "334-2-4334-2-4");
}
fn day1_pre() -> String {
let contents = fs::read_to_string("day1.txt").expect("error reading file");
day1(contents.lines())
}
fn day1<'a>(lines: impl Iterator<Item = &'a str> + Clone) -> String {
lines
.map(|line| {
let v: Result<i32, _> = line.parse();
v.expect("could not parse line as integer")
})
.cycle()
.take(10)
.map(|x| x.to_string())
.collect()
}
但是,此代码之所以有效,是因为测试中有奇怪的.map(|x| *x)
。如果我将其删除,则会收到以下错误:
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, &str> as Iterator>::Item == &str`
--> src/lib.rs:6:16
|
6 | assert_eq!(day1(v), "334-2-4334-2-4");
| ^^^^ expected `str`, found `&str`
...
14 | fn day1<'a>(lines: impl Iterator<Item = &'a str> + Clone) -> String {
| -------------- required by this bound in `day1`
|
= note: expected reference `&str`
found reference `&&str`
我有点理解这个错误。iter
返回&T
,在本例中生成&&str
。我不明白的是,为什么删除map
并将iter
替换为into_iter
(即let v = ["3", "3", "4", "-2", "-4"].into_iter();
)也会失败,并出现相同的错误!
根据the documentation,into_iter
迭代了T
,应该可以在这里工作?
在写这篇文章时,我还尝试用Vec
和into_iter
替换数组,最终结果是let v = vec!["3","3","4","-2","-4"].into_iter();
,并且成功了!但是现在我更困惑了,为什么into_iter
可以为Vec
工作,而Array
不可以呢?
推荐答案
这是通过Rust 1.53 release notes宣布的。IntoIterator
for array是1.53中实现的新增功能,但在2018和2021版本中表现不同:
由于向后兼容性问题,以前没有实现这一点。由于数组引用已实现
IntoIterator
,因此array.into_iter()
已在早期版本中编译,解析为(&array).into_iter()
。
从本版本开始,数组实现IntoIterator,但有一个小的解决办法,以避免中断代码。编译器将继续将array.into_iter()
解析为(&array).into_iter()
,就好像特征实现不存在一样。这只适用于.into_iter()
方法调用语法,不影响for e in [1, 2, 3]
、iter.zip([1, 2, 3])
或IntoIterator::into_iter([1, 2, 3])
等任何其他语法,它们都可以很好地编译。
因为
.into_iter()
的这个特殊情况只是为了避免破坏现有代码,所以在今年晚些时候发布的新版本Rust 2021中删除了它。有关详细信息,请参阅版本声明。
因此,您的代码将使用Rust2021compile just fine
这篇关于是否从&;str;数组中获取迭代器<;item=str&>?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!