Solidity编程语言(12)--结构体struct

使用结构体struct可以自定义数据类型,结构体内可以包含除自身以外的所有数据类型,如果包含自身则会形成递归。

###定义与初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
pragma solidity >=0.4.0 <0.6.0;

contract EgStruct {
mapping (string => Book) bookList;
struct Book{
string name;
uint pages;
string[] contents;
}

struct Reader{
mapping (string => Book) books;
string name;
}

Reader r;
function init() public{
string[] memory b1c = new string[](3);
b1c[0] = "1.0.1";
b1c[1] = "1.0.2";
b1c[2] = "2.0.1";
Book memory b1 = Book("book1",10,b1c);

Book memory b2 = Book({
name:"book2",
pages:20,
contents:b1c
});

Reader memory r1 = Reader("jack");

Reader memory r2 = Reader({
name:"rosh"
});


// Reader memory r2 = Reader(bookList,"jack");
// Reader memory r3 = Reader({
// books:bookList,
// name:"rosh"
// });

r = r2;
r.books["book1"] = b1;
//r2.bookList["book2"] = b2;

//r2.books = bookList;
//r.books = bookList;

}
}
  1. 结构体struct的初始化有两种方式,一种是Book(“book1”,10,b1c),需要按结构体的非mapping定义顺序传入,一种种Book({name:”book2”,pages:20,contents:b1c })

  2. 当结构体中包含mapping成员时,初始化的时候不能对mapping成员进行传参赋值

  3. 结构体的mapping成员变量是不能直接去引用其他mapping的(storage),不管该结构体对象是storage还是memory

  4. 只有结构体对象是状态变量(storage)的,才能使用其mapping成员进行赋值操作
    ###可见性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    pragma solidity >=0.4.0 <0.6.0;

    contract EgStruct {
    struct Book{
    string name;
    uint pages;
    }

    function read(Book memory b) internal{}

    function callTmp(EgStructTmp tmp) public{
    Book memory b = Book("jingpinmei",10);
    tmp.seal(b.name,b.pages);
    }

    }

    contract EgStructSub is EgStruct{
    function write(Book memory b) internal{}
    }

    contract EgStructOut {
    /*function seal(Book memory b) {}*/
    }

    contract EgStructTmp{
    struct Book{
    string name;
    uint pages;
    }
    function seal(string memory name, uint pages) public {
    Book memory b = Book(name, pages);
    }
    }
  5. Solidity中的结构只在当前合约或者子类合约中可用,外部是不可见的,而且使用结构体的函数需要修饰为internal。

  6. 非要这么做的话,则可以通过函数调用进行传递基本类型的数据,然后再次组装成同样的结构体
    ###数组参数
    这里有碰到个问题就是在函数参数不能是不固定的复杂类型参数,下边代码中seal1就无法编译通过

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    pragma solidity >=0.4.0 <0.6.0;

    contract EgStructTmp{
    struct Book{
    string name;
    uint pages;
    }
    function seal1(string memory name, uint pages,string[] memory s) public {
    Book memory b = Book(name, pages);
    }

    function seal2(string memory name, uint pages, string[] memory s) internal {
    Book memory b = Book(name, pages);
    }

    }