DoubleEndedIterator
迭代向后迭代集合的每个元素。
fn clone_backward<List, ItemType>(list: &List) -> List
where
for<'a> &'a List: IntoIterator<Item = &'a ItemType>,
for<'a> <&'a List as IntoIterator>::IntoIter: DoubleEndedIterator,
for<'a> &'a List::IntoIter: DoubleEndedIterator<Item = &'a ItemType>,
List: FromIterator<ItemType> + IntoIterator,
ItemType: Clone,
{
list.into_iter()
.rev()
.cloned()
.collect()
}
fn main() {
let first_list = vec![1, 2, 3, 4, 5];
let second_list: Vec<i32> = clone_backward(&first_list);
assert_eq!(vec![5, 4, 3, 2, 1], second_list);
}
eRror
error[E0277]: the trait bound `for<'a> <&'a _ as IntoIterator>::IntoIter: DoubleEndedIterator` is not satisfied
--> src/main.rs:17:48
|
17 | let second_list: Vec<i32> = clone_backward(&first_list);
| -------------- ^^^^^^^^^^^ the trait `for<'a> DoubleEndedIterator` is not implemented for `<&'a _ as IntoIterator>::IntoIter`
| |
| required by a bound introduced by this call
|
note: this is a known limitation of the trait solver that will be lifted in the future
--> src/main.rs:17:48
|
17 | let second_list: Vec<i32> = clone_backward(&first_list);
| ---------------^^^^^^^^^^^-
| | |
| | the trait solver is unable to infer the generic types that should be inferred from this argument
| add turbofish arguments to this call to specify the types manually, even if it's redundant
note: required by a bound in `clone_backward`
--> src/main.rs:4:51
|
1 | fn clone_backward<List, ItemType>(list: &List) -> List
| -------------- required by a bound in this function
...
4 | for<'a> <&'a List as IntoIterator>::IntoIter: DoubleEndedIterator,
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `clone_backward`
error[E0277]: the trait bound `for<'a> &'a _: DoubleEndedIterator` is not satisfied
--> src/main.rs:17:48
|
17 | let second_list: Vec<i32> = clone_backward(&first_list);
| -------------- ^^^^^^^^^^^ the trait `for<'a> DoubleEndedIterator` is not implemented for `&'a _`
| |
| required by a bound introduced by this call
|
note: required by a bound in `clone_backward`
--> src/main.rs:5:33
|
1 | fn clone_backward<List, ItemType>(list: &List) -> List
| -------------- required by a bound in this function
...
5 | for<'a> &'a List::IntoIter: DoubleEndedIterator<Item = &'a ItemType>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `clone_backward`
help: consider removing the leading `&`-reference
|
17 - let second_list: Vec<i32> = clone_backward(&first_list);
17 + let second_list: Vec<i32> = clone_backward(first_list);
|
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to 2 previous errors
似乎在撰写本文时,特征求解器在间接的情况下无法解决。
fn clone_backward<List, ItemType>(list: &List) -> List
where
for<'a> &'a List: IntoIterator<Item = &'a ItemType>,
for<'a> <&'a List as IntoIterator>::IntoIter: DoubleEndedIterator,
List: FromIterator<ItemType>,
ItemType: Clone,
{
list.into_iter().rev().cloned().collect()
}
fn main() {
let first_list = vec![1, 2, 3, 4, 5];
let second_list: Vec<i32> = clone_backward::<Vec<i32>, i32>(&first_list);
assert_eq!(vec![5, 4, 3, 2, 1], second_list);
}
(请注意,我删除了几个不必要的注释)
您可以进一步优化这一步骤,因此您只需要注释返回类型,因为(通过一点点注释疼痛)向量的元素可以由编译器确定:
fn clone_backward<List>(list: &List) -> List
where
for<'a> &'a List: IntoIterator,
for<'a> <&'a List as IntoIterator>::IntoIter: DoubleEndedIterator,
for<'a> <&'a List as IntoIterator>::Item: std::ops::Deref,
for<'a> <<&'a List as IntoIterator>::Item as std::ops::Deref>::Target: Clone,
for<'a> List: FromIterator<<<&'a List as IntoIterator>::Item as std::ops::Deref>::Target>,
{
list.into_iter().rev().map(|val| (*val).clone()).collect()
}
fn main() {
let first_list = vec![1, 2, 3, 4, 5];
let second_list: Vec<i32> = clone_backward::<Vec<i32>>(&first_list);
assert_eq!(vec![5, 4, 3, 2, 1], second_list);
}
但我认为,在写作时,这是一样的。