#How to borrow instead of move to first if and make second works

25 messages · Page 1 of 1 (latest)

serene gale
#

Just like in title

ripe pike
#
  1. Always push "click for full compiler diagnostic", and 2. It tells you exactly what to do already.
jade moth
serene gale
#

Hm, ok. So first suggestion was to change file.unwrap() to file.as_ref().unwrap() and it worked. However second suggestion was to use as_mut.

fn read_file() {
    let mut file = std::fs::read_to_string("file.txt");

    if file.is_ok() {
        println!("{}", file.as_mut().unwrap());
    }

    if let Ok(file) = file {
        println!("{}", file);
    }
}

And it works also, but Im not sure how. Function unwrap() mutated file now from Result to value of Ok. So file is String now. So how it's possible that in second condition rust was able to use let Ok(file) = file when file is already String?

jaunty crescent
#

where is the point wherein the statement "when file is already String?" is true?

#

like, how do you say that file became a String?

serene gale
#

like here:

if let Ok(file) = file {
        println!("file is String here");
        println!("{}", file);
    }

#

this file.as_mut().unwrap() mutated file to String value

#

Or at least it should, from my understanding

jade moth
#

it doesn't mutate anything

#

?clippy ```rs
fn read_file() {
let mut file = std::fs::read_to_string("file.txt");

if file.is_ok() {
    println!("{}", file.as_mut().unwrap());
}

if let Ok(file) = file {
    println!("{}", file);
}

}

reef sirenBOT
jade moth
#

eh

#

the type of a variable can't change

jaunty crescent
serene gale
#

yeah, I was wrong. Type can't change itself. Looks like it mutates Result values

jaunty crescent
#

it does not either

#

adding a &mut reference does not mean its mutating it per se

serene gale
#

But still not sure how this prevent from moving ownership. as_ref its quite simple - pass by reference instead of moving. What as_mut does here?

jaunty crescent
#

same as as_ref

#

but instead of & u use &mut

#

you can actually check the source code of those methods

#

to see what they do

steady jetty
#
impl<T> Option<T> {
  fn as_ref(&self) -> Option<&T> {
    //remember that matching a reference gives you references to the contents. `x` below is a `&T`
    match self {
      Some(x) => Some(x),
      None => None,
    }
  }

  fn as_mut(&mut self) -> Option<&mut T> {
    match self {
      Some(x) => Some(x),
      None => None,
    }
  }
}
#

They just "move a reference from outside the option to inside it"