Skip to main content

Solidity 结构体

Solidity 中有三种引用类型。分别是数组,结构体和映射类型。其中数组是把一堆类型相同的元素绑在一起,形成一种新的类型。

接下来我们要介绍的结构体是把不同类型的元素绑在一起,形成的一种新类型。结构体类型主要有以下几个方面的应用:

  1. 可以把多个不同类型的数据绑在一起方便进行统一管理
  2. 有了结构体,我们可以一次性向函数传入多个值,而不需要把其展开成多个参数
  3. 同理, 我们也可以使用结构体一次性从函数传回多个值
  4. 结构体加强了 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; // 作者
}
试一试 »

当然,结构体也可以与映射类型互相嵌套,这个部分我们会在映射类型一节详细介绍。