定数は、モジュールレベルで定義される不変の値です。モジュール全体で使用される静的な値に名前を付ける方法としてよく使用されます。例えば、製品のデフォルト価格がある場合、それに対して定数を定義することがあります。定数はモジュールのバイトコードに格納され、使用されるたびに値がコピーされます。

module book::shop_price {
    use sui::coin::Coin;
    use sui::sui::SUI;

    /// ショップでの商品の価格。
    const ITEM_PRICE: u64 = 100;
    /// ショップのオーナー、アドレス。
    const SHOP_OWNER: address = @0xa11ce;

    /// ショップで販売される商品。
    public struct Item { /* ... */ }

    /// ショップから商品を購入する。
    public fun purchase(coin: Coin<SUI>): Item {
        assert!(coin.value() == ITEM_PRICE, 0);

        transfer::public_transfer(coin, SHOP_OWNER);

        Item { /* ... */ }
    }
}

命名規則

定数は大文字で始まる必要があります - これはコンパイラレベルで強制されます。値として使用される定数には、大文字とアンダースコアを使用して単語を区切る規則があります。これは、コード内の他の識別子から定数を目立たせる方法です。エラー定数に対しては例外が設けられており、ECamelCaseで記述されます。

/// ショップで使用される商品の価格。
const ITEM_PRICE: u64 = 100;

/// エラー定数。
const EItemNotFound: u64 = 1;

定数は不変

定数は変更できず、新しい値を割り当てることはできません。これらはパッケージのバイトコードの一部であり、本質的に不変です。

module book::immutable_constants {
    const ITEM_PRICE: u64 = 100;

    // エラーを発生させる
    fun change_price() {
        ITEM_PRICE = 200;
    }
}

設定パターンの使用

アプリケーションの一般的なユースケースは、コードベース全体で使用される一連の定数を定義することです。しかし、定数はモジュールに対してプライベートであるため、他のモジュールからアクセスすることができません。これを解決する一つの方法は、定数をエクスポートする「設定」モジュールを定義することです。

module book::config {
    const ITEM_PRICE: u64 = 100;
    const TAX_RATE: u64 = 10;
    const SHIPPING_COST: u64 = 5;

    /// 商品の価格を返す。
    public fun item_price(): u64 { ITEM_PRICE }
    /// 税率を返す。
    public fun tax_rate(): u64 { TAX_RATE }
    /// 配送料を返す。
    public fun shipping_cost(): u64 { SHIPPING_COST }
}

このようにすることで、他のモジュールが定数をインポートして読み取ることができ、更新プロセスが簡素化されます。定数を変更する必要がある場合、パッケージのアップグレード時に設定モジュールのみを更新すれば良いのです。

リンク

The Move Book へ戻る