结构体(struct)

优质
小牛编辑
117浏览
2023-12-01

Solidity提供struct来定义自定义类型。我们来看看下面的例子:

pragma solidity ^0.4.0;
contract CrowdFunding{
    struct Funder{
        address addr;
        uint amount;
    }
    
    struct Campaign{
        address beneficiary;
        uint goal;
        uint amount;
        uint funderNum;
        mapping(uint => Funder) funders;
    }
    
    uint compaingnID;
    mapping (uint => Campaign) campaigns;
    
    function candidate(address beneficiary, uint goal) returns (uint compaingnID){
        // initialize
        campaigns[compaingnID++] = Campaign(beneficiary, goal, 0, 0);
    }
    
    function vote(uint compaingnID) payable {
        Campaign c = campaigns[compaingnID];
        
        //another way to initialize
        c.funders[c.funderNum++] = Funder({addr: msg.sender, amount: msg.value});
        c.amount += msg.value;
    }
    
    function check(uint comapingnId) returns (bool){
        Campaign c = campaigns[comapingnId];
        
        if(c.amount < c.goal){
            return false;
        }
        
        uint amount = c.amount;
        // incase send much more
        c.amount = 0;
        if(!c.beneficiary.send(amount)){
            throw;
        }
        return true;
    }
}

上面的代码向我们展示的一个简化版的众筹项目,其实包含了一些struct的使用。struct可以用于映射和数组中作为元素。其本身也可以包含映射和数组等类型。

我们不能声明一个struct同时将这个struct作为这个struct的一个成员。这个限制是基于结构体的大小必须是有限的。

虽然数据结构能作为一个mapping的值,但数据类型不能包含它自身类型的成员,因为数据结构的大小必须是有限的。

需要注意的是在函数中,将一个struct赋值给一个局部变量(默认是storage类型),实际是拷贝的引用,所以修改局部变量值时,会影响到原变量。

当然,你也可以直接通过访问成员修改值,而不用一定赋值给一个局部变量,如campaigns[comapingnId].amount = 0