我有下面的代码片段(不要质疑它们的意义;)
1.递归获取的第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>?发布于 2020-01-21 09:27:40
在第二个示例中,FromIterator (这里的Self::Item是T)。因此编译器试图通过查看tail的使用方式来猜测它的类型。当您调用helper (tail, …)时,编译器猜测tail应该具有与helper的第一个参数相同的类型,对于某些未知类型的U,也就是&Vec<U>。但是,&Vec<U>没有实现FromIterator<T>,因此编译器此时退出。
OTOH调用helper (&tail, …)时,编译器猜测&tail应该对某些U具有&Vec<U>类型,因此tail应该具有Vec<U>类型。然后编译器可以继续并确定该U==T,它将tail的完整类型赋予Vec<T>。
顺便说一句,下面是您的第一个helper的更惯用的实现,它避免了不必要的副本。对于第二个问题,也可以做一些类似的事情:
fn helper<T: Clone> (n: usize, current_n: usize, current_xs: &[T], accumulator: Option<&T>) -> Option<T>
{
if current_n > n {
accumulator.cloned()
} else {
let head = current_xs.get (0);
let tail = ¤t_xs[1..];
return if tail.is_empty() {
None
} else {
helper (n, current_n + 1, tail, head)
};
}
}
fn main() {
let v = vec![1, 2, 3, 4, 5];
println!("Element 3: {:?}", helper (3, 0, &v, None));
println!("Element 10: {:?}", helper (10, 0, &v, None));
}发布于 2020-01-21 08:38:34
问题是:
示例1:调用递归函数
return helper(n, current_n + 1, &tail, head); // &tail示例2:使用以下方法调用递归函数:
return helper(tail, accumulator + 1) // tail将tail更改为&tail万事通。目前我无法确切地解释为什么,所以我会等待接受这个正确的答案,并希望其他人能完全回答它。
https://stackoverflow.com/questions/59836651
复制相似问题