Почему появляется заимствованная ошибка, если я использую неизменяемую переменную в разных местах моего кода? - PullRequest
0 голосов
/ 09 июля 2020

Я изучаю ржавчину, и мне трудно понять, почему следующий код не компилируется с ошибкой «Ошибка [E0505]: невозможно выйти из req, потому что он заимствован» в req.into_body () . Если я удалю println! или переместите его перед совпадением, он запустится.

async fn hello_world(req: Request<Body>) -> Result<Response<Body>, Infallible> {
  let mut response = Response::new(Body::empty());

  let method = req.method();
  let path = req.uri().path();

  match (method, path) {
    (&Method::GET, "/") => {
      *response.body_mut() = Body::from("Try POSTing data to /echo");
    }
    (&Method::POST, "/echo") => {
      *response.body_mut() = req.into_body();
    }
    _ => {
      *response.status_mut() = StatusCode::NOT_FOUND;
    }
  };
  println!("{} {}", method, path);

  Ok(response)
}

Я понимаю некоторые заимствования, но я не понимаю, почему положение println что-то меняет, так как я уже определяю неизменяемые переменные которые успешно используются в матче.

1 Ответ

1 голос
/ 09 июля 2020

У вас не может быть изменяемого и неизменяемого заимствования одновременно. В вашем случае это будет преобразование заимствованных типов (возврат method() и uri().path()) в собственные. Вы можете сделать это через ToOwned::to_owned или через явные преобразования ( игровая площадка ):

async fn hello_world(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let mut response = Response::new(Body::empty());

    let method = req.method().clone(); // &Method -> Method
    let path = req.uri().path().to_string(); // &str -> String
    // `req` is not borrowed at this point, so it can be mutated

    match (method.clone(), path.as_str()) {
        (Method::GET, "/") => {
            *response.body_mut() = Body::from("Try POSTing data to /echo");
        }
        (Method::POST, "/echo") => {
            *response.body_mut() = req.into_body();
        }
        _ => {
            *response.status_mut() = StatusCode::NOT_FOUND;
        }
    };
    println!("{} {}", method, path);

    Ok(response)
}
...