常量
常量是在模块级别定义的不可变值。它们通常用作给模块中使用的静态值命名的一种方式。例如,如果有一个产品的默认价格,可以为其定义一个常量。常量存储在模块的字节码中,每次使用时,值都会被复制。
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 }
}
这样,其他模块可以导入和读取常量,并简化更新过程。如果需要更改常量,只需要在包升级期间更新配置模块即可。