如何从迭代器中获取切片?

时间:2015-10-17 17:02:17

标签: rust

我开始使用clippy作为linter。有时,它会显示此警告:

writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be
used with non-Vec-based slices. Consider changing the type to `&[...]`,
#[warn(ptr_arg)] on by default

我将参数更改为切片,但这会在调用端添加样板。例如,代码是:

let names = args.arguments.iter().map(|arg| {
    arg.name.clone()
}).collect();
function(&names);

但现在是:

let names = args.arguments.iter().map(|arg| {
    arg.name.clone()
}).collect::<Vec<_>>();
function(&names);

否则,我收到以下错误:

error: the trait `core::marker::Sized` is not implemented for the type
`[collections::string::String]` [E0277]

所以我想知道是否有办法将Iterator转换为slice或避免在这种特定情况下指定collect ed类型。

1 个答案:

答案 0 :(得分:15)

  

所以我想知道是否有办法将Iterator转换为slice

没有。

迭代器一次只提供一个元素,而切片一次只提供几个元素。这就是为什么您首先需要将Iterator产生的所有元素收集到一个连续数组(Vec)中才能使用切片。

第一个明显的答案是不要担心轻微的开销,尽管我个人更喜欢将类型提示放在变量旁边(我发现它更具可读性):

let names: Vec<_> = args.arguments.iter().map(|arg| {
    arg.name.clone()
}).collect();
function(&names);

另一种选择是function代替Iterator(以及引用的迭代器):

let names = args.arguments.iter().map(|arg| &arg.name);
function(names);

毕竟,迭代器更通用,如果需要,你可以随时“实现”函数内的切片。