How do I use a variable more than once without it copying?

I did the hello world not so long ago and I'm not making much progress since then. Can someone explain what I'm doing wrong please, because it doesn't matter how many help documents I read this doesn't make any sense.

I've created a variable called response and I'm trying to use this a few different times and it's all going wrong.

I've read tutorials where if you assign a variable to another variable then the first variable is dis-guarded, but I'm not assign a variable to another variable. However I'm still having problems.

#[tokio::main]
pub async fn do_api_stuff4() -> Result<(), Box<dyn Error>> {
    let response: reqwest::Response = reqwest::Client::new()
        .get("https://www.themuse.com/api/public/jobs?page=1")
        .header(AUTHORIZATION, "Bearer [AUTH_TOKEN]")
        .header(CONTENT_TYPE, "application/json")
        .header(ACCEPT, "application/json")       
        .send()
        .await
        .unwrap(); 

    println!("one");

    println!("response.error_for_status() {:?}", response.error_for_status());

    println!("two");

    if response.status() != reqwest::StatusCode::OK {
        println!("not OK");
    } else {
        println!("OK");
    }


Ok(())
}

In the line println!("response.error_for_status() {:?}", response.error_for_status()); I use the variable response and then after this I'm not able to use the variable again.

So on compile time the line if response.status() != reqwest::StatusCode::OK { doesn't compile.

I haven't made a copy of the variable, I've just used it.

This is what I get when I compile it.

   Compiling prj_the_muse_api v0.1.0 (/home/matthew/Rust/009 call API/prj_the_muse_api)
error[E0382]: borrow of moved value: `response`
   --> src/mod_api_request_calls.rs:211:8
    |
183 |     let response: reqwest::Response = reqwest::Client::new()
    |         -------- move occurs because `response` has type `Response`, which does not implement the `Copy` trait
...
203 |     println!("response.error_for_status() {:?}", response.error_for_status());
    |                                                           ------------------ `response` moved due to this method call
...
211 |     if response.status() != reqwest::StatusCode::OK {
    |        ^^^^^^^^^^^^^^^^^ value borrowed here after move
    |
note: `Response::error_for_status` takes ownership of the receiver `self`, which moves `response`
   --> /home/matthew/.cargo/registry/src/github.com-1ecc6299db9ec823/reqwest-0.11.16/src/async_impl/response.rs:341:29
    |
341 |     pub fn error_for_status(self) -> crate::Result<Self> {
    |                             ^^^^

For more information about this error, try `rustc --explain E0382`.
error: could not compile `prj_the_muse_api` due to previous error

I don't want a move to occur, I want to be able to use the same variable more than once.

When I look up help documents about moves and copies, it always refers to assigning another variable invoking to move. Which is not what I'm doing, println!("response.error_for_status() {:?}", response.error_for_status()); does not assign the variable response to another variable.

I'm confused.

The error_for_status method is defined to take self (as opposed to &self or &mut self), so it consumes the response when called. Instead, use the error_for_status_ref method that doesn't consume the response.

5 Likes

Thank you for that.

This language is far more complicated than any other computer language I've learned.

The only language I've tried to learn that is even more complex, is not a computer language, it's German.

But thank you you helped a lot.

Well, there's not much complexity in this error. There's a well-defined problem, that you could have inferred by reading the signature of the function and is solvable by a quick scan of the documentation. Even the compiler pointed out where and exactly why it occurs.

You have to understand memory management and indirection, though – which is valuable (or I should say, indispensable) in other languages too. Without understanding memory management and indirection, it's not really possible to write non-trivial programs correctly. Unfortunately, most mainstream languages don't force you to think about this issue much, and let you write buggy programs instead. The fact that Rust exposes these problems and makes you think about them is not a weakness – it's the main strength of the language.

In addition, I find it a bit unfair to compare Rust to the complexity of any natural langue. Complexity in natural languages usually arises from special cases, and as such, is mostly a historical artefact that could have been avoided. Rust's type system is pretty uniform, with very few special cases (that usually help common idioms to be more convenient to express). In other words, Rust is not "hard" for the sake of being hard. It is writing correct programs that is hard, and this language simply doesn't let you get away with anything less.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.