特殊类型 #

一、枚举 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