如何将变量传递给闭包?

时间:2019-12-09 10:42:36

标签: rust syslog rust-tokio

我想将变量log传递给闭包:

#[macro_use]
extern crate slog;
extern crate tokio;

use std::{env, str};

use std::sync::Mutex;
use tokio::codec::{BytesCodec, Decoder};
use tokio::net::TcpListener;
use tokio::prelude::*;

use slog::Drain;

fn main() {
    const PROGRAM_NAME: &'static str = env!("CARGO_PKG_NAME");

    let decorator = slog_term::TermDecorator::new().build();
    let drain = slog_term::FullFormat::new(decorator).build().fuse();
    let drain_mutex = Mutex::new(drain);

    let log = slog::Logger::root(drain_mutex.fuse(), o!());

    let ip = "localhost";
    let tcp_port = 2222;

    let addr = format!("{}:{}", ip, tcp_port).parse().unwrap();

    let listener = TcpListener::bind(&addr).expect("Error. Cannot bind this address");

    info!(log, "TCP Server listening"; "daemon-name" => PROGRAM_NAME, "server-ip" => ip, "server-port" => tcp_port);

    let done = listener
            .incoming()
            .map_err(|e| println!("failed to accept socket; error = {:?}", e))
            .for_each(move |socket| {

                let framed = BytesCodec::new().framed(socket);
                let (mut writer, reader) = framed.split();
                let log = log.clone();

                let processor = reader
                    .for_each(move |bytes| {
                        debug!(log, "{}", format!("TCP Server reading stream: {:?}", bytes); "daemon-name" => PROGRAM_NAME);
                        Ok(())
                    })
                    .and_then(|()| {
                        println!("Socket received FIN packet and closed connection");
                        Ok(())
                    })
                    .or_else(move |err| {
                        let msg = format!("TCP Server - Socket closed with error: {:?})", err);
                        println!("{}", msg);

                        error!(log, "{}", msg;  "daemon-name" => PROGRAM_NAME);
                        Err(err)
                    })
                    .then(|result| {
                        println!("Socket closed with result: {:?}", result);
                        Ok(())
                    });

                 tokio::spawn(processor)
            });

    tokio::run(done);
}
error[E0382]: use of moved value: `log`
  --> src/main.rs:50:30
   |
39 |                 let log = log.clone();
   |                     --- move occurs because `log` has type `slog::Logger<std::sync::Arc<dyn slog::SendSyncRefUnwindSafeDrain<Err = slog::private::NeverStruct, Ok = ()>>>`, which does not implement the `Copy` trait
...
42 |                     .for_each(move |bytes| {
   |                               ------------ value moved into closure here
43 |                         debug!(log, "{}", format!("TCP Server reading stream: {:?}", bytes); "daemon-name" => PROGRAM_NAME);
   |                                --- variable moved due to use in closure
...
50 |                     .or_else(move |err| {
   |                              ^^^^^^^^^^ value used here after move
...
54 |                         error!(log, "{}", msg;  "daemon-name" => PROGRAM_NAME);
   |                                --- use occurs due to use in closure

0 个答案:

没有答案