Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 无法移出'FnMut'闭包中捕获的变量_Rust - Fatal编程技术网

Rust 无法移出'FnMut'闭包中捕获的变量

Rust 无法移出'FnMut'闭包中捕获的变量,rust,Rust,我对错误的理解是: 闭包B是FnMut,它通过获取其所有权来捕获通知者 在闭包B中,send再次需要获得所有权 现在send和Closure B都在修改notificator,从而修改错误 我的理解正确吗?如何解决这个问题?嵌套闭包很棘手 考虑这一点: pub fn create_future( notificator: mpsc::Sender<usize>, proxy: Proxy, ) -> impl Future<Item = (), Error

我对错误的理解是:

  • 闭包B是
    FnMut
    ,它通过获取其所有权来捕获
    通知者
  • 在闭包B中,
    send
    再次需要获得所有权
  • 现在
    send
    和Closure B都在修改
    notificator
    ,从而修改错误

  • 我的理解正确吗?如何解决这个问题?

    嵌套闭包很棘手

    考虑这一点:

    pub fn create_future(
        notificator: mpsc::Sender<usize>,
        proxy: Proxy,
    ) -> impl Future<Item = (), Error = ()> {
        proxy.something()
            .and_then(move |sub| {
                sub.for_each(move |a| { // <---- Closure A
                    proxy.something_else(a)
                        .and_then(move |b| { // <---- Closure B
                            notificator.send(b.len());  // <---- Error!
                            Ok(())
                        })
                        .or_else(|e| {
                            panic!("oops {}", e);
                            Ok(())
                        })
                })
            })
            .map_err(|e| {
                ()
            })
    }
    

    然后,您会看到所看到的错误(除了
    Fn
    vs
    FnMut
    ,这对问题无关紧要)。每次调用外部闭包时,都会重新创建内部闭包(必须这样做,因为它每次都要捕获
    a
    ),但它每次都会尝试通过移动来捕获
    外部闭包。这行不通;第一次之后,
    outer\u s
    被移出,因此无效

    要将此映射回您的代码,说“Closure B captures
    notificator
    ”是错误的,因为不只是一个Closure B。有尽可能多的必要的Closure B,但是通常您嵌套的
    和_然后
    for_每个
    调用都会在该代码段中结束。但只有一个人可以通过移动来捕获

    所以要解决这个问题,您需要确保只有一个闭包B,或者确保每个人都有足够的
    mpsc::Sender
    s

    第一种方法是将闭包从嵌套上下文中拉出

    fn use_a_fn_multiple_times(f: impl Fn(String)) {
        f("foo".to_owned());
        f("bar".to_owned());
    }
    
    fn use_fn_once(f: impl FnOnce() -> Vec<u8>) {
        println!("Bytes: {:?}", f());
    }
    
    fn main() {
      let outer_s = "see:".to_owned();
    
      use_a_fn_multiple_times(|a: String| {
        use_fn_once(move || {
            let mut v = outer_s.into_bytes();
            v.extend(a.into_bytes());
            v
        });
      });
    }
    
    第二种方法涉及大量的
    clone()
    调用,由于我无法对代码进行类型检查,因此我不会尝试编写它


    但是,当所有这些都说了又做了之后,您的代码仍然会失败,因为您正在移出
    代理
    ,同时也在尝试使用它。

    什么是
    代理
    ?你能提供一个“请”吗?“在结束语B中,再次发送需要获得所有权”-听起来不对
    mpsc::Sender::send
    接受
    &self
    。我相信您的问题已经由的答案回答了。如果你不同意,请用你的问题来解释不同之处。否则,我们可以将此问题标记为已回答。谢谢。非常有用。我最终通过添加
    clone()
    s来修复它。或者在我的例子中,当我想使用一个
    struct
    时,需要在嵌套的
    FnMut
    中使用顶级参数来调用它,然后我首先用
    #[derivate(clone)]
    注释该结构,以便能够使用
    clone()
    fn use_a_fn_multiple_times(f: impl Fn(String)) {
        f("foo".to_owned());
        f("bar".to_owned());
    }
    
    fn use_fn_once(f: impl FnOnce() -> Vec<u8>) {
        println!("Bytes: {:?}", f());
    }
    
    fn main() {
      let outer_s = "see:".to_owned();
    
      use_a_fn_multiple_times(|a: String| {
        use_fn_once(move || {
            let mut v = outer_s.into_bytes();
            v.extend(a.into_bytes());
            v
        });
      });
    }
    
    let closure_b = move |b| {
        notificator.send(b.len());
        Ok(())
    };
    proxy.something()
        .and_then(move |sub| {
            sub.for_each(move |a| { // <---- Closure A
                proxy.something_else(a)
                    .and_then(closure_b)
                    .or_else(|e| {
                        panic!("oops {}", e);
                        Ok(())
                    })
            })
        })
        .map_err(|e| {
            ()
        })
    
    let closure_b = move |b| {
        notificator.send(b.len());
        Ok(())
    };
    let closure_a = move |a| {
        proxy.something_else(a)
            .and_then(closure_b)
            .or_else(|e| {
                panic!("oops {}", e);
                Ok(())
            })
    };
    proxy.something()
        .and_then(move |sub| {
            sub.for_each(closure_a)
        })
        .map_err(|e| {
            ()
        })