Skip to main content

選項 (Option)

Option 是一種表示「可能存在也可能不存在」的可選值的類型。Move 中 Option 的概念借鑒自 Rust,它是 Move 中非常實用的原始類型。Option 定義在 標準庫 中,定義如下:

module std::option;

/// 對可能存在也可能不存在的值的抽象。
public struct Option<Element> has copy, drop, store {
vec: vector<Element>
}

參閱 std::option 模組完整文件

std::option 模組在每個模組中都會被隱式匯入,因此您不需要添加明確的匯入語句。

Option 類型是一個具有 Element 類型參數的泛型類型。它包含一個名為 vec 的欄位,這是一個 Elementvector(向量)。該向量的長度可以為 0 或 1,分別代表值的缺失或存在。

注意:您可能會對 Option 是一個包含 vectorstruct 而不是 列舉 (enum) 感到驚訝。這是由於歷史原因:Option 在 Move 支援列舉之前就被添加進去了。

Option 類型有兩個變體:SomeNoneSome 變體包含一個值,而 None 變體表示值的缺失。Option 類型用於以類型安全的方式表示值的缺失,從而避免對空值或 undefined 值的需求。

實務應用

為了展示為何需要 Option 類型,讓我們看一個範例。假設一個應用程式接收使用者輸入並將其儲存在變數中。有些欄位是必填的,有些是選填的。例如,使用者的中間名 (middle name) 是選填的。雖然我們可以使用空字串來表示中間名的缺失,但這需要額外的檢查來區分空字串和確實缺失的中間名。相反,我們可以使用 Option 類型來表示中間名。

module book::user_registry;

use std::string::String;

/// 代表使用者記錄的結構。
public struct User has drop {
first_name: String,
middle_name: Option<String>,
last_name: String,
}

/// 使用給定的欄位建立新的 `User` 結構。
public fun register(
first_name: String,
middle_name: Option<String>,
last_name: String,
): User {
User { first_name, middle_name, last_name }
}

在前面的範例中,middle_name 欄位的類型為 Option<String>。這意味著 middle_name 欄位既可以包含封裝在 Some 中的 String 值,也可以是明確為空的(由 None 表示)。使用 Option 類型使該欄位的可選性質變得明確,避免了歧義,也不需要額外的檢查來區分空字串和缺失的中間名。

建立與使用 Option 值

Option 類型以及 std::option 模組在 Move 中是隱式匯入的。這意味著您可以直接使用 Option 類型,而不需要 use 語句。

要建立 Option 類型的值,您可以使用 option::someoption::none 方法。Option 值也支援多種操作(借用將在 參照 (references) 章節中討論):

// `option::some` 建立包含值的 `Option` 值。
let mut opt = option::some(b"Alice");

// `option::none` 建立不含值的 `Option`。我們需要指定類型,
// 因為無法從上下文推斷。
let empty : Option<u64> = option::none();

// `option.is_some()` 如果 option 包含值,則回傳 true。
assert_eq!(opt.is_some(), true);
assert_eq!(empty.is_none(), true);

// 內部值可以被 `borrow` 和 `borrow_mut`。
assert_ref_eq!(opt.borrow(), &b"Alice");

// `option.extract` 從 option 中取出值,留下空的 option。
let inner = opt.extract();

// `option.is_none()` 如果 option 是 None,則回傳 true。
assert_eq!(opt.is_none(), true);

延伸閱讀