昨天提到了「borrow」的概念,今天要來更深入一點
除了借用出去,其實還可以做一點修改喔
沿用昨天的例子
fn main() {
let shop1 = ["milk", "tea", "coffee"];
let shop2 = &shop1;
}
為了慶祝盛大開幕, shop2 店希望能來個開幕限定商品,需要將 milk 與 tea 結合,變成 milk tea,不過原本的 milk 與 tea 還是會販售
在之前的文章提到,變數的值以後會改變的話,我們可以加上 mut
不過在借用的時候並不是在原本的值上面加上 mut
喔(好像有點難理解,直接下程式碼)
由於 Array 在宣告後就不能做變動,這邊我們就改成 Vec
,並且加上 mut
fn main() {
let mut shop1 = vec!["milk", "tea", "coffee"];
let shop2 = &shop1;
shop2.push("milk tea");
}
來看一下執行結果
這邊寫著 shop2 不可用可修改的方式借用
> cargo run
error[E0596]: cannot borrow `*shop2` as mutable, as it is behind a `&` reference
--> src/main.rs:5:5
|
5 | shop2.push("milk tea");
| ^^^^^^^^^^^^^^^^^^^^^^ `shop2` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
3 | let shop2 = &mut shop1;
| +++
For more information about this error, try `rustc --explain E0596`.
warning: `hello_world` (bin "hello_world") generated 1 warning
error: could not compile `hello_world` (bin "hello_world") due to previous error; 1 warning emitted
由於能修改的權限本身還是在 shop1 上,
借出去的時候並沒有把修改權借給 shop2 ,
如果要讓 shop2 可修改,我們需要在 & 後面加上 mut
fn main() {
let mut shop1 = vec!["milk", "tea", "coffee"];
let shop2 = &mut shop1;
shop2.push("milk tea");
println!("shop2's sell {:?}", shop2)
}
> cargo run
shop2's sell ["milk", "tea", "coffee", "milk tea"]
但如果我們一次要借給很多店呢?
fn main() {
let mut shop1 = vec!["milk", "tea", "coffee"];
let shop2 = &mut shop1;
let shop3 = &mut shop1;
shop2.push("milk tea");
shop3.push("coffee milk");
println!("shop2's sell {:?}", shop2);
println!("shop3's sell {:?}", shop3);
}
執行後會有這個訊息:不能同時以可修改的方式借出多次
> cargo run
error[E0499]: cannot borrow `shop1` as mutable more than once at a time
--> src/main.rs:4:17
|
3 | let shop2 = &mut shop1;
| ---------- first mutable borrow occurs here
4 | let shop3 = &mut shop1;
| ^^^^^^^^^^ second mutable borrow occurs here
5 |
6 | shop2.push("milk tea");
| ---------------------- first borrow later used here
For more information about this error, try `rustc --explain E0499`.
error: could not compile `hello_world` (bin "hello_world") due to previous error
但如果以不修改的方式呢?
fn main() {
let shop1 = vec!["milk", "tea", "coffee"];
let shop2 = shop1;
let shop3 = shop1;
println!("shop2's sell {:?}", shop2);
println!("shop3's sell {:?}", shop3);
}
單純的借用就可以借給多個變數囉
> cargo run
fn main() {
let shop1 = vec!["milk", "tea", "coffee"];
let shop2 = &shop1;
let shop3 = &shop1;
println!("shop2's sell {:?}", shop2);
println!("shop3's sell {:?}", shop3);
}
幫大大總結一下,rsut的借用規則:
感謝大大補充