iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0

所有權是什麼

就是今天這個值的所有權是誰的,

我將值借給你,代表將值的所有權借給你用,不過之後還是得要還我

有點抽象,我們直接用例子來解釋好了

所有權的概念 - move

假設我們今天有個變數,為 drink1 與 drink2

我們先定義了 drink1

fn main() {
    let drink1 = String::from("Milk Tea");
}

接下來再定義 drink2 的值為 drink1 的值

fn main() {
    let drink1 = String::from("Milk Tea");

    let drink2: String = drink1;
}

我們把 drink1 與 drink2 分別印出來

fn main() {
    let drink1 = String::from("Milk Tea");

    let drink2: String = drink1;

    println!("這是 1 號飲品 {}", drink1);
    println!("這是 2 號飲品 {}", drink2);
}

還沒跑 cargo run 以前就會發現有紅色蚯蚓跑出來了

來看一下他要告訴我們什麼錯誤訊息

borrow of moved value: drink1 value borrowed here after move rustc

意思是說 drink1 的值給(move)了 drink2

在 Rust 中,有幾個所有權的規則可以記在腦中

  1. 每個值都會有一個 owner
  2. 每個值一次只能有一個 owner
  3. 當 owner 離開 scope ,值就會消失

剛剛的錯誤訊息告訴我們 drink1 的值給了 drink2 ,

這個值的 owner 是 drink2 而非 drink1,

因此 drink1 沒有值,無法印出

那我們來試著印出 drink2

fn main() {
    let drink1 = String::from("Milk Tea");

    let drink2: String = drink1;
    
    println!("這是 2 號飲品 {}", drink2);
}

可以知道目前 drink2 為 "Milk Tea" 的 owner

> cargo run

這是 2 號飲品 Milk Tea

上次有提到變數分別會存在 Stack 與 Heap

Stack 會存放以下這些資料:

指標(pointer) 會指向該變數的 heap 位置
容量 表示 heap 位置中可以容納多少個元素
長度 目前變數中有多少元素

Heap 就會用來存放 value

https://ithelp.ithome.com.tw/upload/images/20230930/20150947mCgj1EYNAv.jpg

用現實生活中的例子來說,

假設今天 drink1 有一支筆,

給了 drink2 後,這支比目前就在 drink2 手上了

drink1 因為沒有這支筆所以無法使用這支筆


上一篇
Day 14 Trait & Derive
下一篇
Day 16 - Ownership part 2
系列文
成為程式界的 F1 賽車手,用 30 天認識 Rust 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
hello world
iT邦新手 5 級 ‧ 2023-09-30 20:29:01

不是借而不還,rust裡的借用(borrow)和移動(move)是兩個不同的意思。

borrow of moved value: drink1 value borrowed here after move rustc

上面這句是rust警告我們違反了借用規則,因為我們進行的操作是**「借用已移動的值(borrow of moved value)」**,因為所有權規則,該值已被移動(moved),所以不復存在,自然也無法借用。借用的地方在println的巨集裡,這個巨集會借用(borrow)傳入的變數。

rust裡面,如文中提到的所有權規則,因為一次只能有一個所有權擁有者,所以

fn main() {
    let drink1 = String::from("Milk Tea");  // 字串"Milk Tea"的owner是 drink1
    let drink2: String = drink1;            // 所有權由drink1 移交(move)給 drink 2
    println!("這是 2 號飲品 {}", drink2);
}

把move當成「給」比較合理,當我的筆(move)了同事A,這個筆的所有者就是那位同事A,所以有其他人來找我借筆,因為我給出去了,所以我沒有東西可以借我同事。

感謝回饋,有大大回饋我才又更理解一點了 /images/emoticon/emoticon29.gif

我要留言

立即登入留言