常量

常量是在模块级别定义的不可变值。它们通常用作给模块中使用的静态值命名的一种方式。例如,如果有一个产品的默认价格,可以为其定义一个常量。常量存储在模块的字节码中,每次使用时,值都会被复制。

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

    /// The price of an item in the shop.
    const ITEM_PRICE: u64 = 100;
    /// The owner of the shop, an address.
    const SHOP_OWNER: address = @0xa11ce;

    /// An item sold in the shop.
    public struct Item { /* ... */ }

    /// Purchase an item from the shop.
    public fun purchase(coin: Coin<SUI>): Item {
        assert!(coin.value() == ITEM_PRICE, 0);

        transfer::public_transfer(coin, SHOP_OWNER);

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

命名约定

常量必须以大写字母开头 - 这在编译器级别是强制执行的。对于用作值的常量,有一个约定,使用大写字母和下划线来分隔单词。这是一种让常量在代码中突出显示的方式。一个例外是错误常量,它们使用ECamelCase编写。

/// Price of the item used at the shop.
const ITEM_PRICE: u64 = 100;

/// Error constant.
const EItemNotFound: u64 = 1;

常量是不可变的

常量无法更改或赋予新值。它们是包字节码的一部分,并且是固有的不可变的。

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

    // 会产生错误
    fun change_price() {
        ITEM_PRICE = 200;
    }
}

使用配置模式

应用程序的常见用例是定义一组在整个代码库中使用的常量。但是由于常量是模块的私有内容,无法从其他模块中访问。解决这个问题的方法之一是定义一个"config"模块,导出常量。

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

    /// Returns the price of an item.
    public fun item_price(): u64 { ITEM_PRICE }
    /// Returns the tax rate.
    public fun tax_rate(): u64 { TAX_RATE }
    /// Returns the shipping cost.
    public fun shipping_cost(): u64 { SHIPPING_COST }
}

这样,其他模块可以导入和读取常量,并简化更新过程。如果需要更改常量,只需要在包升级期间更新配置模块即可。

链接