Solidity学习::(10)自定义结构体

自定义结构体


定义


 跟其他语言类似

  //学生
  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]);
  }
}

返回结果:

Solidity学习::(10)自定义结构体_第1张图片

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)将两个合约部署

Solidity学习::(10)自定义结构体_第2张图片

(2)以合约B的地址为参数,调用合约StructAcrossInitial 中的call函数

(3)返回

 Solidity学习::(10)自定义结构体_第3张图片

你可能感兴趣的:(区块链学习)