自定义结构体
定义
跟其他语言类似
//学生
struct Student{
string name;
int num;
}
//班级
struct Class{
string clsName;
//学生的列表
Student[] students;
mapping(string=>Student)index;
}
初始化
1、直接初始化
如果我们声明的自定义类型为A,我们可以使用A(变量1,变量2, ...)的方式来完成初始化。
测试代码:
pragma solidity ^0.4.0;
contract StructInitial{
struct A{
string name;
mapping(address=>A) map;
int age;
string[] cources;
}
function init() returns (string, int, string){
string[] memory cources = new string[](1);
cources[0] = "Chemistry";
//按顺序填值,初始化时,可以跳过映射类型
A memory a = A("Jack", 23, cources);
return (a.name, a.age, cources[0]);
}
}
返回结果:
2、 命名初始化
可以使用类似JavaScript的命名参数初始化的方式,通过传入参数名和对应值的对象。这样做的好处在于可以不按定义的顺序传入值。
//按命名参数的方式进行初始化
Student memory s = Student({
age : 10,
name : "Jack",
cources: crs
});
3、结构体中映射的初始化
学习完映射再回头来看
结构体的可见性
结构体由于是不对外可见的,所以你只可以在当前合约,或合约的子类中使用。
包含自定义结构体作为参数的函数均需要声明为internal的。
pragma solidity ^0.4.0;
contract A{
struct S{
string para1;
int para2;
}
function f(S s) internal{
//...
}
function f1() public{
//当前类中使用结构体
S memory s = S("Test", 10);
f(s);
}
}
contract B is A{
function g(){
//字类中使用结构体
S memory s = S("Test", 10);
//调用父类方法
f(s);
}
}
合约间结构体的调用解决方案
手动将要返回的结构体拆解为基本类型
测试代码:
- 合约StructAcrossInitial中有一个结构体A
- 现需要调用合约B中的函数对结构体A的数据进行处理
- 因此将结构体A中的数据拆分,逐个作为参数进行调用
pragma solidity ^0.4.0;
contract StructAcrossInitial{
struct A{
string para1;
int para2;
}
function call(B b) returns(string,int){ //这里的参数为B b,即需要传入合约B实例的地址
A memory a = A("Test", 10);
return b.g(a.para1, a.para2);
}
}
contract B{
function g(string para1, int para2) returns(string,int){
//你要实现的内容
return (para1,para2);
}
}
操作步骤:
(1)将两个合约部署
(2)以合约B的地址为参数,调用合约StructAcrossInitial 中的call函数
(3)返回