1. 程式人生 > >Solidity學習::(10)自定義結構體

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

返回結果:

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)返回