Solidity 结构体
Solidity 中有三种引用类型。分别是数组,结构体和映射类型。其中数组是把一堆类型相同的元素绑在一起,形成一种新的类型。
接下来我们要介绍的结构体是把不同类型的元素绑在一起,形成的一种新类型。结构体类型主要有以下几个方面的应用:
- 可以把多个不同类型的数据绑在一起方便进行统一管理
- 有了结构体,我们可以一次性向函数传入多个值,而不需要把其展开成多个参数
- 同理, 我们也可以使用结构体一次性从函数传回多个值
- 结构体加强了 Solidity 的表达能力(结构体可以与其他结构体或者数组,映射类型互相嵌套)。使得代码更加易读。
定义一个结构体
我们来介绍一下如何定义一个结构体。定义结构体需要用到 struct
关键字。下面的例子中定义了一个 Book
的结构体,里面包含了两个元素,分别是书名和价格。
struct Book {
string title; // 书名
uint price; // 价格
}
结构体的声明
接下来我们介绍一下如何声明结构体。我们在「数据位置」一节介绍过:对于每个引用类型的声明我们都必须加上「数据位置」修饰符(如果是声明状态变量的话可以不加)。所以对于结构体也不例外。如下面的例子所示,我们声明了一个变量 book
,它的类型是 Book 。
Book memory book;
根据上面的例子,我们不难总结出声明一个结构体的格式如下:
StructName DataLocation varName;
其中 StructName
是你定义的结构体名称, DataLocation
是数据位置。然后 varName
是给结构体变量取的任意名字。
结构体的初始化
你有两种方法来初始化结构体。一种是以键值的形式,指定每个成员的初始值。如下所示:
Book memory book1 = Book(
{
title: "my book title",
price: 25
}
);
注意你必须为每一个成员赋初始值,不能省略任何一个成员。
第二种是比较简短的形式,依据你定义结构体时各个成员的顺序一一给定初始化值,如下所示:
Book memory book2 = Book("my book title", 25);
同样地,你必须为每一个成员赋初始值,不能省略任何一个成员。
获取结构体成员
要获取结构体成员我们可以使用 .
操作符。如下面例子所示:
Book memory book3;
book3.title = "my book title"; // 给结构体成员赋值
book3.price = 25; // 给结构体成员赋值
console.log("title: %s", book3.title); // 获取结构体成员值
结构体可以和数组,映射类型互相嵌套
有了结构体,我们可以更方便管理数据了。不仅如此,结构体还可以和数组,映射类型(下一节我们介绍映射类型)互相嵌套。这样一来,又大大增强了 Solidtiy 的表达能力。例如我们可以创建一个书库数组,你可以每买一本书,就把书添加到数组里。如下所示:
Book[] public lib; // Book数组,状态变量
function addNewBook(Book memory book) public {
lib.push(book);
}
此外,结构体里面也可以有数组:
例如,每本书可能会有多个联合作者,我们可以在里面增加一个作者的数组
struct Book {
string title; // 书名
uint price; // 价格
string[] author; // 作者
}
当然,结构体也可以与映射类型互相嵌套,这个部分我们会在映射类型一节详细介绍。