0

Recently, I started to learn a new programming language, rust. It has an interesting feature called move and borrow, but it is really hard to understand in some situations.

To my opinion, if a variable prefixed with a &, it's borrow, but the following code confused me.

fn iter(lst: &[String]) {
    //item variable is prefix with '&', so i think it's borrow, but the compiler tells me it's move.
    //the compiler suggests to remove '&', completely contrary to what I thought.
    for &item in lst {
        println!("item is: {}", item)
    }
}

Is there a intuitive way to distinguish the move and borrow.

gaols
  • 341
  • 5
  • 13
  • 1
    in `for item in lst`, `item` would be a `&String`. The `&` isn't you "marking" `item` as a borrow, quite the opposite, its trying to *destructure* the borrow into an owned value, which won't work for `String` – kmdreko Jul 31 '20 at 02:52
  • @kmdreko could you please further explains the reason why `destructure the borrow into an owned value, which won't work for String`? – gaols Jul 31 '20 at 03:06
  • 1
    The destructuring is attempting to get a `String` from a `&String`, from the compiler error "cannot move out of a shared reference", it is trying to *move* the string out of the iterator result but it cannot do so because you don't have exclusive ownership (rust won't let you invalidate other references). The compiler could destructure a `&T` to a `T` by *copying* but that is only done for types that implement `Copy`, which `String` does not. – kmdreko Jul 31 '20 at 03:17
  • 1
    @gaols the left hand of the `in` is a *pattern*. Generally speaking, patterns are the inverse of expressions by design: the way you create something in an expression is the way you uncreate it in a pattern. So in a pattern `&` doesn't take a reference, it dereferences. I wrote generally because that's not always the case e.g. `*` doesn't exist in patterns, instead there's a dedicated `ref` keyword to take / create references. – Masklinn Jul 31 '20 at 07:33

0 Answers0