我有以下代码片段:
1.递归地获取Vec的第n个元素
fn helper<T: Clone>(n: usize, current_n: usize, current_xs: &Vec<T>, accumulator: Option<T>) -> Option<T> {
if current_n > n {
accumulator
} else {
let head = current_xs.get(0).cloned();
let tail = current_xs.clone().into_iter().skip(1).collect();
return helper(n, current_n + 1, &tail, head);
}
}
2.递归获取Vec的长度
fn helper<T: Clone>(current_xs: &Vec<T>, accumulator: usize) -> usize {
if current_xs.is_empty() {
accumulator
} else {
let tail = current_xs.clone().into_iter().skip(1).collect();
return helper(tail, accumulator + 1)
}
}
我的问题是关于这条线:
let tail = current_xs.clone().into_iter().skip(1).collect();
在第一个示例中,tail
变量的类型为Vec<T>
,而在第二个示例中,tail
变量的类型为&Vec<?>
。
问题:
- 为什么?为什么返回两种不同类型的代码行?
- 如何在第二个例子中返回
Vec<T>
?
2条答案
按热度按时间8ftvxx2r1#
在第二个例子中,
collect
可以返回任何实现FromIterator<Self::Item>
的东西(这里的Self::Item
是T
)。所以编译器试图通过查看tail
的使用方式来猜测它的类型。当您调用helper (tail, …)
时,编译器猜测tail
应该与helper
的第一个参数具有相同的类型,对于某些未知类型U
,也称为&Vec<U>
。然而,&Vec<U>
并没有实现FromIterator<T>
,所以编译器在这一点上退出。OTOH当你调用
helper (&tail, …)
时,编译器猜测&tail
应该有&Vec<U>
类型的U
,因此tail
应该有Vec<U>
类型。然后编译器可以继续并确定U==T
,这给出了tail
的完整类型为Vec<T>
。顺便说一句,这里是第一个
helper
的更惯用的实现,它避免了不必要的复制。类似的事情可以为第二个做:Playground
disho6za2#
问题是:
**示例1:**调用递归函数,
**示例2:**调用递归函数:
将
tail
更改为&tail
,一切正常。目前我不能确切地解释为什么,所以我会等待接受这是正确的答案,并希望其他人可以完全回答它。Rust Playground