特殊类型 #
一、枚举 enum #
1.1 枚举定义 #
solidity
contract EnumDemo {
// 定义枚举
enum Status {
Pending, // 0
Active, // 1
Completed, // 2
Cancelled // 3
}
// 状态变量
Status public currentStatus;
constructor() {
currentStatus = Status.Pending;
}
}
1.2 枚举值访问 #
solidity
contract EnumAccess {
enum Status { Pending, Active, Completed, Cancelled }
Status public status;
function setStatus(Status _status) public {
status = _status;
}
function setStatusByValue(uint8 _value) public {
status = Status(_value);
}
function getStatus() public view returns (Status) {
return status;
}
function getStatusValue() public view returns (uint8) {
return uint8(status);
}
}
1.3 枚举操作 #
solidity
contract EnumOperations {
enum State { Created, Locked, Inactive }
State public state;
constructor() {
state = State.Created;
}
function advance() public {
if (state == State.Created) {
state = State.Locked;
} else if (state == State.Locked) {
state = State.Inactive;
}
}
function reset() public {
delete state; // 重置为第一个值(Created)
}
function isActive() public view returns (bool) {
return state == State.Locked;
}
}
1.4 枚举示例:订单状态 #
solidity
contract OrderSystem {
enum OrderStatus {
Created, // 已创建
Paid, // 已支付
Shipped, // 已发货
Delivered, // 已送达
Cancelled, // 已取消
Refunded // 已退款
}
struct Order {
uint256 id;
address buyer;
uint256 amount;
OrderStatus status;
uint256 createdAt;
}
mapping(uint256 => Order) public orders;
uint256 public orderCount;
event OrderCreated(uint256 indexed id, address indexed buyer, uint256 amount);
event OrderStatusChanged(uint256 indexed id, OrderStatus newStatus);
function createOrder() public payable returns (uint256) {
require(msg.value > 0, "Amount must be greater than 0");
orderCount++;
orders[orderCount] = Order({
id: orderCount,
buyer: msg.sender,
amount: msg.value,
status: OrderStatus.Created,
createdAt: block.timestamp
});
emit OrderCreated(orderCount, msg.sender, msg.value);
return orderCount;
}
function payOrder(uint256 _orderId) public payable {
Order storage order = orders[_orderId];
require(order.buyer == msg.sender, "Not buyer");
require(order.status == OrderStatus.Created, "Invalid status");
require(msg.value == order.amount, "Incorrect amount");
order.status = OrderStatus.Paid;
emit OrderStatusChanged(_orderId, OrderStatus.Paid);
}
function shipOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
require(order.status == OrderStatus.Paid, "Invalid status");
order.status = OrderStatus.Shipped;
emit OrderStatusChanged(_orderId, OrderStatus.Shipped);
}
function deliverOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
require(order.status == OrderStatus.Shipped, "Invalid status");
order.status = OrderStatus.Delivered;
emit OrderStatusChanged(_orderId, OrderStatus.Delivered);
}
function cancelOrder(uint256 _orderId) public {
Order storage order = orders[_orderId];
require(order.buyer == msg.sender, "Not buyer");
require(
order.status == OrderStatus.Created ||
order.status == OrderStatus.Paid,
"Cannot cancel"
);
order.status = OrderStatus.Cancelled;
payable(order.buyer).transfer(order.amount);
emit OrderStatusChanged(_orderId, OrderStatus.Cancelled);
}
}
二、用户定义类型 #
2.1 类型定义 #
solidity
contract UserDefinedTypes {
// 使用type定义新类型
type UFixed256x18 is uint256; // 定点数,18位小数
type Role is uint8; // 角色类型
type TokenId is uint256; // 代币ID
}
2.2 类型包装与解包 #
solidity
contract UserDefinedTypeDemo {
type UFixed256x18 is uint256;
UFixed256x18 public value;
function setValue(UFixed256x18 _value) public {
value = _value;
}
function setValueFromUint(uint256 _value) public {
value = UFixed256x18.wrap(_value);
}
function getValueAsUint() public view returns (uint256) {
return UFixed256x18.unwrap(value);
}
}
2.3 用户定义类型示例 #
solidity
contract TokenTypeSystem {
type TokenId is uint256;
type Price is uint256;
mapping(TokenId => Price) public tokenPrices;
mapping(TokenId => address) public tokenOwners;
TokenId public nextTokenId;
event TokenMinted(TokenId indexed id, address indexed owner, Price price);
event PriceUpdated(TokenId indexed id, Price newPrice);
constructor() {
nextTokenId = TokenId.wrap(1);
}
function mint(Price _price) public returns (TokenId) {
TokenId tokenId = nextTokenId;
tokenOwners[tokenId] = msg.sender;
tokenPrices[tokenId] = _price;
nextTokenId = TokenId.wrap(TokenId.unwrap(nextTokenId) + 1);
emit TokenMinted(tokenId, msg.sender, _price);
return tokenId;
}
function updatePrice(TokenId _tokenId, Price _newPrice) public {
require(tokenOwners[_tokenId] == msg.sender, "Not owner");
tokenPrices[_tokenId] = _newPrice;
emit PriceUpdated(_tokenId, _newPrice);
}
function getPrice(TokenId _tokenId) public view returns (uint256) {
return Price.unwrap(tokenPrices[_tokenId]);
}
}
三、函数类型 #
3.1 函数类型定义 #
solidity
contract FunctionTypeDemo {
// 函数类型声明
// function(参数) [internal|external] [pure|view|payable] returns (返回值)
// 内部函数类型
function(uint256, uint256) internal pure returns (uint256) internalAdd;
// 外部函数类型
function(uint256) external returns (uint256) externalFunc;
}
3.2 函数类型使用 #
solidity
contract FunctionTypeUsage {
// 定义函数类型
typedef function(uint256, uint256) pure returns (uint256) BinaryOp;
// 函数类型变量
BinaryOp public operation;
// 具体函数
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
function multiply(uint256 a, uint256 b) public pure returns (uint256) {
return a * b;
}
// 设置操作
function setOperation(BinaryOp _op) public {
operation = _op;
}
// 使用操作
function calculate(uint256 a, uint256 b) public view returns (uint256) {
require(operation != BinaryOp(0), "Operation not set");
return operation(a, b);
}
}
3.3 函数类型作为参数 #
solidity
contract FunctionAsParameter {
// 函数类型作为参数
function apply(
function(uint256, uint256) pure returns (uint256) _op,
uint256 a,
uint256 b
) public pure returns (uint256) {
return _op(a, b);
}
// 具体函数
function add(uint256 a, uint256 b) public pure returns (uint256) {
return a + b;
}
function subtract(uint256 a, uint256 b) public pure returns (uint256) {
return a - b;
}
// 使用
function testAdd() public pure returns (uint256) {
return apply(add, 10, 5); // 15
}
function testSubtract() public pure returns (uint256) {
return apply(subtract, 10, 5); // 5
}
}
3.4 函数类型作为返回值 #
solidity
contract FunctionAsReturnValue {
// 函数类型作为返回值
function getOperation(bool _isAdd)
public
pure
returns (function(uint256, uint256) pure returns (uint256))
{
if (_isAdd) {
return add;
} else {
return multiply;
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function multiply(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
// 使用
function test() public pure returns (uint256) {
function(uint256, uint256) pure returns (uint256) op = getOperation(true);
return op(10, 5); // 15
}
}
3.5 回调函数模式 #
solidity
contract CallbackPattern {
// 回调函数类型
function(uint256) internal callback;
event ResultReady(uint256 result);
function registerCallback(function(uint256) internal _callback) public {
callback = _callback;
}
function process(uint256 value) public {
uint256 result = value * 2;
if (callback != function(uint256) internal(0)) {
callback(result);
}
emit ResultReady(result);
}
}
contract CallbackUser {
uint256 public lastResult;
function handleResult(uint256 _result) internal {
lastResult = _result;
}
function register(CallbackPattern _processor) public {
_processor.registerCallback(handleResult);
}
}
四、内部与外部函数类型 #
4.1 内部函数类型 #
solidity
contract InternalFunctionType {
// 内部函数类型:只能在当前合约或继承合约中使用
function(uint256) internal returns (uint256) internalFunc;
function setInternalFunc(function(uint256) internal returns (uint256) _func) public {
internalFunc = _func;
}
function process(uint256 value) public returns (uint256) {
require(internalFunc != function(uint256) internal returns (uint256)(0), "Not set");
return internalFunc(value);
}
}
4.2 外部函数类型 #
solidity
contract ExternalFunctionType {
// 外部函数类型:可以引用其他合约的函数
function(uint256) external returns (uint256) externalFunc;
function setExternalFunc(address _contract, bytes4 _selector) public {
externalFunc = function(uint256) external returns (uint256)(
abi.encodeWithSelector(_selector)
);
}
function call(uint256 value) public returns (uint256) {
require(address(externalFunc) != address(0), "Not set");
return externalFunc(value);
}
}
五、综合示例 #
5.1 状态机合约 #
solidity
contract StateMachine {
enum State {
Idle,
Processing,
Completed,
Failed
}
State public currentState;
// 状态转换函数类型
function(State) internal returns (State) transitionFunc;
event StateChanged(State from, State to);
constructor() {
currentState = State.Idle;
}
function setTransition(function(State) internal returns (State) _func) public {
transitionFunc = _func;
}
function advance() public {
require(transitionFunc != function(State) internal returns (State)(0), "No transition");
State oldState = currentState;
currentState = transitionFunc(currentState);
emit StateChanged(oldState, currentState);
}
// 默认转换逻辑
function defaultTransition(State _current) internal pure returns (State) {
if (_current == State.Idle) return State.Processing;
if (_current == State.Processing) return State.Completed;
return _current;
}
}
5.2 策略模式 #
solidity
contract StrategyPattern {
// 策略函数类型
function(uint256[], uint256) pure returns (uint256[]) Strategy;
Strategy public currentStrategy;
// 策略实现
function filterGreaterThan(uint256[] memory arr, uint256 threshold)
public
pure
returns (uint256[] memory)
{
uint256 count = 0;
for (uint256 i = 0; i < arr.length; i++) {
if (arr[i] > threshold) count++;
}
uint256[] memory result = new uint256[](count);
uint256 index = 0;
for (uint256 i = 0; i < arr.length; i++) {
if (arr[i] > threshold) {
result[index++] = arr[i];
}
}
return result;
}
function filterLessThan(uint256[] memory arr, uint256 threshold)
public
pure
returns (uint256[] memory)
{
uint256 count = 0;
for (uint256 i = 0; i < arr.length; i++) {
if (arr[i] < threshold) count++;
}
uint256[] memory result = new uint256[](count);
uint256 index = 0;
for (uint256 i = 0; i < arr.length; i++) {
if (arr[i] < threshold) {
result[index++] = arr[i];
}
}
return result;
}
function setStrategy(Strategy _strategy) public {
currentStrategy = _strategy;
}
function execute(uint256[] memory arr, uint256 threshold)
public
view
returns (uint256[] memory)
{
require(currentStrategy != Strategy(0), "Strategy not set");
return currentStrategy(arr, threshold);
}
}
六、最佳实践 #
6.1 枚举使用建议 #
solidity
// 推荐:使用枚举表示固定状态
enum Status { Pending, Active, Completed }
// 不推荐:使用整数常量
// uint8 constant PENDING = 0;
// uint8 constant ACTIVE = 1;
// uint8 constant COMPLETED = 2;
6.2 用户定义类型建议 #
solidity
// 推荐:为语义不同的值创建类型
type TokenId is uint256;
type UserId is uint256;
// 避免:TokenId和UserId混用
TokenId token = TokenId.wrap(1);
UserId user = UserId.wrap(1);
// token = user; // 编译错误,类型不匹配
6.3 函数类型建议 #
solidity
// 推荐:明确声明可见性和状态修饰符
function(uint256) internal pure returns (uint256) func;
// 注意:外部函数类型存储为address和selector
// 内部函数类型存储为函数指针
七、总结 #
特殊类型要点:
| 类型 | 说明 | 使用场景 |
|---|---|---|
| enum | 枚举,有限状态集合 | 状态机、选项 |
| 用户定义类型 | type定义的新类型 | 类型安全、语义清晰 |
| 函数类型 | 函数指针 | 回调、策略模式 |
使用建议:
- 使用枚举表示有限状态
- 使用用户定义类型增强类型安全
- 函数类型用于灵活的设计模式
- 注意内部和外部函数类型的区别
接下来,让我们学习运算符!
最后更新:2026-03-27