什么是Solidity结构体?

  • Alchemy
  • 发布于 2022-10-26 18:24
  • 阅读 24

本文介绍了Solidity中的结构体(struct),讲解了结构体的定义、创建,以及如何在智能合约中使用。展示了如何声明和初始化结构体的不同方法,以及如何将结构体映射。

在Solidity中有不同的基本数据类型,如 uint(无符号整数)boolstring,但是作为一个区块链开发者,你可能需要一个可以自定义的灵活数据类型。struct 是Solidity中的一种数据结构格式,允许将不同数据类型的变量组合成一个变量或用户定义的类型。

本文将向你介绍Solidity中的结构体,演示它们的功能和工作原理。最后,我们将解释如何使用结构体来创建更强大的智能合约。

什么是Solidity结构体?

结构体是Solidity中的一种创新的数据结构格式,允许将不同数据类型的变量组合成一个变量或用户定义的类型。 一旦数据类型被分组到结构体中,结构体的名称就代表结构体内的变量子集。

可以将结构体视为一种容器,里面包含不同类型的对象,因此当你移动这个容器时,容器内的所有项目也会随之移动。因此,当Solidity开发者声明或调用结构体的名称时,结构体会根据其内部的数据类型做出响应。

以下是一个Solidity结构体的示例:

contract MyVault{
struct Vault{
    address creator;
        string name;
        address users;
        uint amount;
    }
}

上面的结构体示例包含了address creator、string name、address users和uint amount的变量。

Solidity结构体代码示例

本节将向你展示如何在Solidity中定义和创建结构体的示例代码。我们还将演示结构体声明的两种选择。最后,我们将展示如何导入和初始化结构体。

如何在Solidity中定义和创建结构体

结构体代码类似于Javascript中的对象声明。尽管外观相似,但语法有所不同。Solidity结构体始终采用以下格式:

struct name{
string theWord;
      uint theFigure;
      bool polar;
}

以下是如何定义和创建Solidity结构体的步骤:

  1. 通过编写struct关键字创建结构体,这告诉Solidity编译器前面的类型是用户自定义类型

  2. 命名结构体,这将与结构体中打包的变量进行共同引用

  3. 使用花括号,因为使用任何其他形式的括号,如方括号或圆括号都将无法编译

如果你不使用花括号,你将在Remix中生成ParserError消息。

未使用花括号的解析错误消息。未使用花括号的解析错误消息。

  1. 声明数据类型及其对应的变量

在上面的示例中,它们是string theWord、uint theFigure和bool polarData。这是你声明结构体子集的地方。在智能合约中声明结构体后,我们可以在代码的后续中调用结构体名称。

开发者提示:

  • 只使用花括号

  • 每个结构体成员末尾使用分号

  • 如果声明的数据类型和输入的变量不匹配,Solidity将抛出错误

  • 智能合约可以包含多个结构体,通过它们的关键字区分

如何声明Solidity结构体

你可以在合约内或合约外声明结构体。知道在哪里声明Solidity结构体取决于你的需求。让我们看看两种结构体声明的选项。

在合约外声明结构体

pragma solidity ^0.8.16;
// 这是一个在合约外声明的结构体
struct floorOverlay{
string carpet;
    string rug;
}

在上面的示例中,结构体_floorOverlay_是在智能合约外声明的,代码库中的所有合约都可以调用它。最好在智能合约外声明结构体,以创建更适用于所有合约的结构体,而不是仅限于某个合约,其可能有特定的结构体。

此外,如果希望智能合约访问相同的集合结构体,可以在_pragma_后立即声明,而不是在每个智能合约中分别创建结构体。

在合约内声明结构体

结构体_carpet_在智能合约内,因此该结构体的功能仅限于当前合约。没有其他合约可以调用它的名称。

contract CarpetContract{
// 这个结构体在此合约内声明
struct carpet{
string name;
        uint length;
        uint breadth;
        bool shipped;
     }
}

如何导入Solidity结构体

结构体可以从一个智能合约导入到另一个合约,帮助开发者节省时间并创建可重用的代码。以下是两个智能合约的示例,其中一个创建了结构体,另一个将导入它。

pragma solidity ^0.8.16;
// 在Remix上将此合约保存为“struct”
contract A{
struct vaccine{
      string name;
          uint id;
          bool vaccinated;
       }
}

在导入时,你应该避免的错误是:第二个合约的名称应与你想要导入的结构体名称相同。否则,Solidity编译器将无法识别它,导致错误。

pragma solidity ^0.8.16;
import "./struct.sol";
contract Vaccine{
// 将其存储为状态变量
Vaccine public drug;
// 接下来定义更多状态变量和函数
}

如何初始化Solidity结构体

即使你已声明并创建结构体,但在各种Solidity函数中使用它,你仍需为其分配某个初始值。你可以通过以下3种方法初始化结构体:(i) 键值对方法,(ii) 定义和更新方法,(iii) 使用括号参数。

1. 键值对方法

在此方法中,你将选择结构体中的每种键类型,并为其分配值。

Vaccine memory tetanus = Vaccine({vaccinated: false, name: "Tetanus", id: 3});

此方法的语法并不严格,你可以选择不按照结构体中类型的顺序。

2. 定义和更新方法

此初始化方法的语法是,你必须先输入一个变量来存储结构体,然后使用该变量来访问和命名结构体的每个成员。以下代码为说明:

Vaccine memory polio
polio.name = "Polio";
    polio.id = 3;
    polio.vaccinated = true;

请注意,大多数开发者不会使用此方法,因为它较长。

3. 使用括号参数

如果你想使用此方法,必须调用结构体的名称,存储其内存,并以顺序给结构体的成员赋值。以下是一个示例:

Vaccine memory measles = Vaccine("Measles", 2, false);

在此,“measles”是存储此初始化的变量,我们还按结构体中列出的内容声明了参数。请记住要在括号内用撇号包含声明的名称,以便Solidity编译器能够识别它。

Solidity结构体的使用案例

本节展示了使用Solidity跟踪智能合约中用户信息的用例。结构体在该用例中进行了映射。

结构体可以在Solidity中被映射吗?

结构体可以作为值类型在Solidity中被映射,以便跟踪与结构体的任何成员相关的信息。 请看以下代码示例:

pragma solidity ^0.8.16;
contract MapStructs{
struct DaoMembers{
        address owner;
            string name;
            string guild;
            bool voted;
         }
         mapping(address => DaoMembers) members;
         mapping (bool => mapping(address => DaoMembers)) memberStatus;
     }

在这个合约中,特定DAO每个成员的详细信息被分类。我们创建了两个映射:一个是简单映射,另一个是嵌套映射。

在简单映射中,我们映射每个成员的地址到结构体中,以方便查找特定成员。此外,使用嵌套映射可以更方便地跟踪DAO成员的地址以及他们是否投票。

因为映射总是采用键类型 => 值类型的语法,所以结构体必须始终声明为值类型,而不是键类型。否则,你将收到错误信息。

Remix错误显示如果尝试将结构体声明为键类型会发生什么。Remix错误显示如果尝试将结构体声明为键类型会发生什么。

总结 - 结构体在Solidity中的本质是什么?

Solidity中的结构体允许开发者创建适合其构建目标的自定义类型。这些自定义类型类似于容器,容纳了其他相关的数据类型。

  • 原文链接: alchemy.com/overviews/so...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Alchemy
Alchemy
江湖只有他的大名,没有他的介绍。