std::iter::FlatMap.clone() 可以吗?

7

我正在尝试在FlatMap中创建所有可能的物品对:

possible_children.clone().flat_map(|a| possible_children.clone().map(|b| (a,b)))

为了做到这一点,我正在尝试克隆一个FlatMap,我在文档中看到FlatMap结构体实现了clone方法。但是似乎不可能创建一个满足trait bounds的FlatMap。
这是我得到的错误:
error: no method named `clone` found for type `std::iter::FlatMap<std::ops::Range<u16>, _, [closure@src/main.rs:30:47: 33:27]>` in the current scope
  --> src/main.rs:37:66
   |
37 |         possible_children.clone().flat_map(|a| possible_children.clone().map(|b| (a,b)))
   |                                                                  ^^^^^
   |
   = note: the method `clone` exists but the following trait bounds were not satisfied: `[closure@src/main.rs:30:47: 33:27] : std::clone::Clone`

看文档,我发现:

impl<I, U, F> Clone for FlatMap<I, U, F>
    where F: Clone, I: Clone, U: Clone + IntoIterator, U::IntoIter: Clone

并且

impl<I, U, F> Iterator for FlatMap<I, U, F>
    where F: FnMut(I::Item) -> U, I: Iterator, U: IntoIterator

看起来F既受到Clone特质的限制,又受到FnMut特质的限制,但是不可能有东西同时实现FnMutClone

文档中存在一个无法调用的方法似乎很奇怪,所以我一定漏掉了什么。

请问有人能为我澄清一下吗?

MVCE:

fn main() {
    let possible_children = (0..10).flat_map(|x| (0..10).map(|y| (x,y)));

    let causes_error = possible_children.clone().flat_map(|a|
        possible_children.clone().map(|b| (a,b) )
    ).collect();

    println!("{:?}",causes_error);
}

你试图使用的 possible_children 的值是多少,导致出现了该错误? - Dogbert
可能的子节点的实际值有些复杂,但这会产生相同的错误:let possible_children = (0..10).flat_map(|x| (0..10).map(|y| (x,y) ) ); - Michael Ratliff
2个回答

8

一个类型可以同时实现 FnMutClone 并没有固有的原因,但目前闭包似乎没有实现 Clone。这里是一个来自2015年的关于此事的简短讨论。我还没有找到更近期的讨论。

我能够构建这个例子,在我的结构体上实现了 FnMut,从而通过不稳定的特性克隆了一个 FlatMap,需要使用nightly编译器 (playground):

#![feature(unboxed_closures)]
#![feature(fn_traits)]
struct MyFun {
    pub v: usize,
}

impl FnOnce<(usize,)> for MyFun {
    type Output = Option<usize>;
    extern "rust-call" fn call_once(self, args: (usize,)) -> Self::Output {
        Some(self.v + 1 + args.0)
    }

}

impl FnMut<(usize,)> for MyFun {
    extern "rust-call" fn call_mut(&mut self, args: (usize,)) -> Self::Output {
        self.v += 1;
        if self.v % 2 == 0 {
            Some(self.v + args.0)
        } else {
            None
        }
    }
}

impl Clone for MyFun {
    fn clone(&self) -> Self {
        MyFun{v: self.v}
    }
}

fn main() {
    let possible_children = (0..10).flat_map(MyFun{v:0});
    let pairs = possible_children.clone().flat_map(|x| possible_children.clone().map(move |y| (x,y) ) );
    println!("possible_children={:?}", pairs.collect::<Vec<_>>());
}

4

实际上,他想要同一个迭代器的两个副本的笛卡尔积。因此,他仍然需要克隆迭代器作为第二个参数传递给.cartesian_product(),对吗? - Francis Gagné

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接