iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Web 3

Smart-Contract Language: Move系列 第 13

Day 13 Advanced Topics: Ownership

  • 分享至 

  • xImage
  •  

Move VM 實現了類似 Rust 的所有權系統,最好的解釋是在 Rust Book 中 (連結在最下面)。
簡單來說,就是 Move 透過所有權系統來管理內存,該系統具有一組編譯器檢查的規則,如果違反則程序將無法編譯。

每個變量只有一個所有者範圍,當所有者範圍結束時,擁有的變量將被刪除

Owner 是一個擁有變量的作用域,變量既可以在此範圍內定義,也可以作為參數傳遞到範圍內。
Move 中唯一著作用域是函數。

每個變量只有一個所有者,當一個變量作為參數傳遞給函數時,該函數將成為新的所有者,並解該變量不再屬於第一個函數。

example:

script {
    use {{sender}}::M;

    fun main() {
        // Module::T is a struct
        let a : Module::T = Module::create(10);

				// 變量 a 傳遞到 main function, 之後的任何地方都無法再取的 a
        M::value(a);

				// a 已不被 main function 擁有,會出現錯醋
        M::value(a);
    }
}

我們看一下 value function 內部發生了什麼。

module M {
    // create_fun skipped
    struct T { value: u8 }

    public fun create(value: u8): T {
        T { value }
    }

		// value function 取得參數控制權
    public fun value(t: T): u8 {
				// 可以在 function 內部任何地方使用 t
        t.value
    }
		// function 結束, t 被 drop, 只有 type 是 u8 的值回傳
		// t 被刪掉,不存在
}

如果不想讓原本參數的值被 drop 掉,我們可以返回一個帶有原始變量和結果的元祖 (T, u8) ,不過 Move 有一個更好的解決方案。

移動和複製

首先,您需要了解 Move VM 的工作原理,以及將值傳遞給函數時會發生什麼。VM 中有兩個字節碼指令:MoveLocCopyLoc - 它們都可以分別手動使用關鍵字 movecopy

如果您需要將值傳遞給函數(它正在被移動的位置)並保存變量的副本,可以使用關鍵字copy

script {
		...
    fun main() {
        let a : Module::T = Module::create(10);

				// 我們使用 copy 將 local 變量 a 複製到函數裡當參數
        M::value(copy a);
        M::value(a); // local 變量 a 一樣可以使用
    }
}

通過複製一個值,我們複製了它並增加了我們程序的內存大小,因此可以使用它 - 但是當複製大量數據時,它可能會在內存方面變得昂貴。請記住 - 在區塊鏈中,每個字節都很重要並影響執行價格,因此copy一直使用可能會花費很多 gas 費用。
因此我們需要搭配上篇所介紹的 Reference 來避免不必要的複製。
讓我們 Move to Day14

相關連結:

Rust Book: https://doc.rust-lang.org/stable/book/ch04-01-what-is-ownership.html


上一篇
Day 12 Advanced Topics: References
下一篇
Day 14 Advanced Topics: Generics
系列文
Smart-Contract Language: Move30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言