Hi All! Welcome to the Reading Club for Rust’s “The Book” (“The Rust Programming Language”). This is week 1 (the beginning!!).

Have a shot at going through “the reading” and post any thoughts, confusions or insights here

“The Reading”

The Twitch Stream

What’s Next Week?

  • Chapters 3 and 4
  • Start thinking about challenges or puzzles to try as we go in order to get some applied practice!
    • EG, Advent of Code
    • Maybe some basic/toy web apps such as a “todo”
  • maegul (he/they)OPM
    link
    fedilink
    English
    arrow-up
    2
    ·
    edit-2
    9 个月前

    Thanks!

    Seems I gotta dig into the borrow checker before thinking too much about this!

    Otherwise, compiling your code snippet is a nice illustration of how helpful the compiler tries to be … lots of tips in the output there! To anyone else, just try running rustc on this, with the second println! uncommented and see the output, which is half error half linting.


    For variables that are passed by reference, the ‘&’ is about whether the ownership of that memory address is transferred or not.

    Yea. So if the second println! were uncommented, how could we compile this? From what you’ve said, I’d guess that & means “borrow” (ie, not “move” ownership).

    So if we alter abc to take a &String type and not String, and therefore only “borrow” the variable, and then pass in &v and not v to pass in a “borrowed” variable, it should compile.

    fn abc(v: &String) {
        println!("v is {}", v);
    }
    
    fn main() {
        let mut v=String::from("ab");
        v.push('c');
        abc(&v);
    
        println!("v is {}", v);
    }
    

    It seems to!

    Of course, as the compiler suggests, we could instead just pass in v.clone() which presumably creates a new variable and effectively “passes by value”.


    Digging in a bit more, what happens if abc (tries to) mutate the variable?

    We can add v.push('X') to abc and see if we get different printouts. As the compiler would tell us, we would need to make the argument v mutable for this to work.

    fn abc(mut v: String) {
    
        v.push('X');
        println!("v is {}", v);
    }
    
    fn main() {
        let mut v=String::from("ab");
        v.push('c');
        abc(v.clone());
    
        println!("v is {}", v);
    }
    
    // OUTPUT:
    // v is abcX
    // v is abc
    

    I’m not clear on why I don’t have to declare that the v.clone() is mutable in anyway though.

    What about trying the same with a "borrowed’ variable?

    Well we need mutable borrowed variables, so necessary adjustments to the types of abc and its call in main. And adding an additional mutation of v in main after abc is called, and we get two different println outputs, with each mutation applying to the same variable.

    fn abc(v: &mut String) {
    
        v.push('X');
        println!("v is {}", v);
    }
    
    fn main() {
        let mut v=String::from("ab");
        v.push('c');
    
        abc(&mut v);
    
        v.push('Y');
    
        println!("v is {}", v);
    }
    
    // OUTPUT
    // v is abcX
    // v is abcXY
    
    • ericjmorey@programming.dev
      link
      fedilink
      English
      arrow-up
      2
      ·
      9 个月前

      Seems I gotta dig into the borrow checker before thinking too much about this!

      It’s covered in detail in chapter 4.