towry / n

Lots of notes here, check out the issues.
http://git.io/vEsyU
MIT License
4 stars 0 forks source link

Rust pattern match #160

Closed towry closed 4 months ago

towry commented 3 years ago
> cargo test

error[E0384]: cannot assign twice to immutable variable `value`
   --> src/second.rs:100:13
    |
99  |         list.peek_mut().map(|&mut value| {
    |                                   -----
    |                                   |
    |                                   first assignment to `value`
    |                                   help: make this binding mutable: `mut value`
100 |             value = 42
    |             ^^^^^^^^^^ cannot assign twice to immutable variable          ^~~~~

list.peek_mut 方法会返回一个 Option<&mut T> 类型的值,然后在一个闭包的参数里进行模式匹配的时候,我们如果用 &mut value 那么就是说,这个 value 会被赋值,赋什么值呢?根据 pattern match 的规则,会把 &mut T中的 T 赋给变量 value,因为 value 是不可变的变量,所以只能在 pattern match 的时候被编译器赋值一次,当在下面的 value = 42 再次赋值的时候会报错,提示你 value 是不可变的,如果要修改,需要告诉编译器(通过加 mut value 的形式),在 pattern match 的时候,请以 mutable 的形式声明这个变量。

所以在 pattern match 的时候,ref, mut, 这些关键词不会影响 pattern 是否会被 match ,只会影响 matched 后的结果是怎么被赋值的。

https://doc.rust-lang.org/reference/patterns.html#annotations:8zeJtiAdEeyQzS-Xje2jiQ

Patterns that consist of only an identifier, possibly with a mut, match any value and bind it to that identifier. This is the most commonly used pattern in variable declarations and parameters for functions and closures.

上面说到了 match pattern 会在 match 有结果的时候进行赋值,那么赋值就涉及到了所有权 ownership 的转变。如果这个值是 Copy 的,那么只会浅拷贝。但是如果是 String 这种不能 copy 的,那么就会使用 move 语意,原来的变量会失去所有权。这种情况会造成很多不便,所以最好使用 ref 告诉编译器请使用借用的方式而不是 move 的方式。