iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Web 3

Smart-Contract Language: Move系列 第 12

Day 12 Advanced Topics: References

  • 分享至 

  • xImage
  •  

Move 有兩種類型的引用

  • 不可變 &
    • 只讀、不能修改
  • 可變 &mut
    • 可修改

example

let foo = Foo { x: 3, y: true };
let foo_ref: &Foo = &foo;
let y: bool = foo_ref.y;  // reading a field via a reference to the struct
let x_ref: &u64 = &foo.x;

let x_ref_mut: &mut u64 = &mut foo.x;
*x_ref_mut = 42;         // modifying a field via a mutable reference

Move 提供了用於創建和擴展引用以及將可變引用轉換為不可變引用的運算符。

  • &e
    • 創建一個不可變的引用e
  • &mut e
    • 創建可變引用e
  • &e.f
    • 創建對 struct e 字段的不可變引用 f
  • &mut e.f
    • 創建對 struct e 字段的可變引用 f
  • freeze(e)
    • 將可變引用轉換為不可變引用。

&e.f and &mut e.f 運算符既可以用於創建對結構的新引用,也可以用於擴展現有引用:

let s = S { f: 10 };
let f_ref1: &u64 = &s.f; // works
let s_ref: &S = &s;
let f_ref2: &u64 = &s_ref.f // also works

在 Struct 篇章有說過,當兩個 Struct 在同一個 Module 時,可以使用多字段表達式拿到。可以同時搭配這邊介紹的可變和不可變運算符。

struct A { b: B }
struct B { c : u64 }
fun f(a: &A): &u64 {
  &a.b.c
}

結合 C* 語法

可以讀取可變和不可變引用已生成引用值的副本。

注意,只能編寫可變引用。

  • *e
    • 讀取指向的值 e
  • *e1 = e2
    • e1 使用 e2 來更新值

為了讀取引用,基礎類型必須具有 copy 能力,防止複製資源值

address 0x3 {
module M {
    struct Coin { amount: u64 }

    fun copy_resource_via_ref_bad(c: Foo) {
	    let c_ref = &c;
	    let counterfeit: Foo = *c_ref; // 會 error, 解決辦法是在 Coin type 加上 copy 能力
    }
}
}

為了寫入引用,類型必須具有寫入引用將丟棄舊值 ( drop ) 的能力,此規則可以防止破壞資源值

address 0x3 {
module M {
    struct Coin { amount: u64 }

		fun destroy_resource_via_ref_bad(ten_coins: Coin, c: Coin) {
	    let ref = &mut ten_coins;
	    *ref = c; // not allowed--would destroy 10 coins! 解決辦法是在 Coin type 加上 drop 能力
		}

}
}

子類型化

通過 freeze 推斷,Move 類型檢查器可以將 &mut T 視為 &T ,因為可變引用可以在需要不可變引用的上下文始中使用。

address 0x42 {
module Example {
    fun read_and_assign(store: &mut u64, new_value: &u64) {
        *store = *new_value
    }

    fun subtype_examples() {
        let x: &u64 = &0;
        let y: &mut u64 = &mut 1;

        x = &mut 1; // valid
        y = &2; // invalid!, 要使用 &mut 2

        read_and_assign(y, x); // valid
        read_and_assign(x, y); // invalid!
    }
}
}

在許多語言都有 Reference, 而 Move 主要使用可變和不可變進行控制,並搭配 type 能力來避免各種開發上的預防錯誤。讓我們 Move to Day13


上一篇
Day 11 Advanced Topics: Global Storage Structures / Operators
下一篇
Day 13 Advanced Topics: Ownership
系列文
Smart-Contract Language: Move30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言