Option は、存在するかどうかわからないオプションの値を表す型です。Move の Option の概念は Rust から借用したもので、Move では非常に便利なプリミティブです。Option標準ライブラリで定義されており 、次のように定義されています。

File: move-stdlib/source/option.move

// File: move-stdlib/source/option.move
/// 存在するかもしれないし、しないかもしれない値の抽象化。
struct Option<Element> has copy, drop, store {
    vec: vector<Element>
}

'std::option' モジュールはすべてのモジュールに暗黙的にインポートされるため、インポートを追加する必要はありません。

Optionは、型パラメータElementを取るジェネリック型です。単一のフィールドvecを持ち、これはElementのベクターです。ベクターは長さ0または1を持つことができ、これを使用して値の存在または不在を表します。 Option型には、SomeNoneの2つのバリアントがあります。Someバリアントは値を含み、Noneバリアントは値の不在を表します。Option型は、型安全な方法で値の不在を表現するために使用され、空または未定義の値を避けるために使用されます。

実際の使用例

Option型が必要な理由を示すために、例を見てみましょう。

ユーザー入力を受け取り、それを変数に格納するアプリケーションを考えてみます。いくつかのフィールドは必須で、いくつかはオプションです。

例えば、ユーザーのミドルネームはオプションです。ミドルネームの不在を表すために空の文字列を使用することもできますが、空の文字列とミドルネームの欠如を区別するために追加のチェックが必要になります。代わりに、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フィールドがString値を含むか、空であるかのいずれかであることを意味します。これにより、ミドルネームがオプションであることが明確になり、空の文字列とミドルネームの欠如を区別するための追加のチェックが不要になります。

オプションの使用

Option型を使用するにはstd::optionモジュールをインポートしてOption型を使用する必要があります。その後、someまたはnoneメソッドを使用してOption値を作成できます。

// `option::some` は値を持つ `Option` 値を作成します。
let mut opt = option::some(b"Alice");

// `option.is_some()` は、オプションが値を含んでいる場合に true を返します。
assert!(opt.is_some(), 1);

// 内部の値は `borrow` および `borrow_mut` で借用できます。
assert!(opt.borrow() == &b"Alice", 0);

// `option.extract` はオプションから値を取り出し、オプションを空にします。
let inner = opt.extract();

// `option.is_none()` は、オプションが None の場合に true を返します。
assert!(opt.is_none(), 2);

The Move Book へ戻る