# 结构体(struct)
`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`
- Solidity语言
- 入门说明
- Solidity智能合约文件结构
- 智能合约源文件的基本要素概览
- 值类型
- 类型
- 布尔
- 整型
- 地址
- 字节数组
- 小数
- 字符串
- 十六进制字面量
- 枚举
- 函数
- 引用类型
- 引用类型
- 数据位置
- 数组
- 数据结构
- 杂项
- 映射
- 左值运算符
- 类型间的转换
- 类型推断
- 单位
- 货币单位
- 时间单位
- 语言内置特性
- 特殊变量及函数
- 数学和加密函数
- 地址相关
- 进阶
- 入参和出参
- 控制结构
- 函数调用
- 创建合约实例
- 表达式的执行顺序
- 赋值
- 作用范围和声明
- 异常
- 内联汇编
- 合约详解
- 合约
- 可见性或权限控制
- 访问函数
- 函数修改器
- 常状态变量
- 回退函数
- 事件
- 继承
- 接口
- 其它
- 库
- 状态变量的存储模型
- 内存变量的存局
- 调用数据的布局