Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(06_arrayandstruct): fix markdown's warning #567

Merged
merged 1 commit into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 06_ArrayAndStruct/ArrayAndStruct.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ contract StructTypes {
_student.score = 100;
}

// 方法2:直接引用状态变量的struct
// 方法2:直接引用状态变量的struct
function initStudent2() external{
student.id = 1;
student.score = 80;
Expand Down
130 changes: 77 additions & 53 deletions 06_ArrayAndStruct/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,130 +9,154 @@ tags:

# WTF Solidity极简入门: 6. 引用类型, array, struct

我最近在重新学solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。
我最近在重新学Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。

欢迎关注我的推特:[@0xAA_Science](https://twitter.com/0xAA_Science)

所有代码开源在github(64个star开微信交流群,已开[填表加入](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform);128个star录教学视频): [github.com/AmazingAng/WTFSolidity](https://github.com/AmazingAng/WTFSolidity)

-----
这一讲,我们将介绍`solidity`中的两个重要变量类型:数组(`array`)和结构体(`struct`)。
这一讲,我们将介绍`Solidity`中的两个重要变量类型:数组(`array`)和结构体(`struct`)。

## 数组 array
数组(`Array`)是`solidity`常用的一种变量类型,用来存储一组数据(整数,字节,地址等等)。数组分为固定长度数组和可变长度数组两种:

数组(`Array`)是`Solidity`常用的一种变量类型,用来存储一组数据(整数,字节,地址等等)。数组分为固定长度数组和可变长度数组两种:

- 固定长度数组:在声明时指定数组的长度。用`T[k]`的格式声明,其中`T`是元素的类型,`k`是长度,例如:
```solidity

```solidity
// 固定长度 Array
uint[8] array1;
bytes1[5] array2;
address[100] array3;
```
```

- 可变长度数组(动态数组):在声明时不指定数组的长度。用`T[]`的格式声明,其中`T`是元素的类型,例如:
```solidity

```solidity
// 可变长度 Array
uint[] array4;
bytes1[] array5;
address[] array6;
bytes array7;
```
**注意**:`bytes`比较特殊,是数组,但是不用加`[]`。另外,不能用`byte[]`声明单字节数组,可以使用`bytes`或`bytes1[]`。`bytes` 比 `bytes1[]` 省gas。
```

**注意**:`bytes`比较特殊,是数组,但是不用加`[]`。另外,不能用`byte[]`声明单字节数组,可以使用`bytes`或`bytes1[]`。`bytes` 比 `bytes1[]` 省gas。

### 创建数组的规则
在solidity里,创建数组有一些规则:

在Solidity里,创建数组有一些规则:

- 对于`memory`修饰的`动态数组`,可以用`new`操作符来创建,但是必须声明长度,并且声明后长度不能改变。例子:
```solidity

```solidity
// memory动态数组
uint[] memory array8 = new uint[](5);
bytes memory array9 = new bytes(9);
```
- 数组字面常数(Array Literals)是写作表达式形式的数组,用方括号包着来初始化array的一种方式,并且里面每一个元素的type是以第一个元素为准的,例如`[1,2,3]`里面所有的元素都是`uint8`类型,因为在solidity中如果一个值没有指定type的话,默认就是最小单位的该type,这里 `uint` 的默认最小单位类型就是`uint8`。而`[uint(1),2,3]`里面的元素都是`uint`类型,因为第一个元素指定了是`uint`类型了,我们都以第一个元素为准。
```

下面的例子中,如果没有对传入 `g()` 函数的数组进行 `uint` 转换,是会报错的
- 数组字面常数(Array Literals)是写作表达式形式的数组,用方括号包着来初始化array的一种方式,并且里面每一个元素的type是以第一个元素为准的,例如`[1,2,3]`里面所有的元素都是`uint8`类型,因为在Solidity中,如果一个值没有指定type的话,默认就是最小单位的该type,这里 `uint` 的默认最小单位类型就是`uint8`。而`[uint(1),2,3]`里面的元素都是`uint`类型,因为第一个元素指定了是`uint`类型了,我们都以第一个元素为准

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
下面的例子中,如果没有对传入 `g()` 函数的数组进行 `uint` 转换,是会报错的。

contract C {
function f() public pure {
g([uint(1), 2, 3]);
}
function g(uint[3] memory _data) public pure {
// ...
```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract C {
function f() public pure {
g([uint(1), 2, 3]);
}
function g(uint[3] memory _data) public pure {
// ...
}
}
}
```
```

- 如果创建的是动态数组,你需要一个一个元素的赋值。
```solidity

```solidity
uint[] memory x = new uint[](3);
x[0] = 1;
x[1] = 3;
x[2] = 4;
```
```

### 数组成员

- `length`: 数组有一个包含元素数量的`length`成员,`memory`数组的长度在创建后是固定的。
- `push()`: `动态数组`拥有`push()`成员,可以在数组最后添加一个`0`元素,并返回该元素的引用。
- `push(x)`: `动态数组`拥有`push(x)`成员,可以在数组最后添加一个`x`元素。
- `pop()`: `动态数组`拥有`pop()`成员,可以移除数组最后一个元素。

**Example:**

![6-1.png](./img/6-1.png)

## 结构体 struct

`Solidity`支持通过构造结构体的形式定义新的类型。结构体中的元素可以是原始类型,也可以是引用类型;结构体可以作为数组或映射的元素。创建结构体的方法:

```solidity
// 结构体
struct Student{
uint256 id;
uint256 score;
}
// 结构体
struct Student{
uint256 id;
uint256 score;
}

Student student; // 初始一个student结构体
Student student; // 初始一个student结构体
```

给结构体赋值的四种方法:

```solidity
// 给结构体赋值
// 方法1:在函数中创建一个storage的struct引用
function initStudent1() external{
Student storage _student = student; // assign a copy of student
_student.id = 11;
_student.score = 100;
}
// 给结构体赋值
// 方法1:在函数中创建一个storage的struct引用
function initStudent1() external{
Student storage _student = student; // assign a copy of student
_student.id = 11;
_student.score = 100;
}
```

**Example:**

![6-2.png](./img/6-2.png)

```solidity
// 方法2:直接引用状态变量的struct
function initStudent2() external{
student.id = 1;
student.score = 80;
}
// 方法2:直接引用状态变量的struct
function initStudent2() external{
student.id = 1;
student.score = 80;
}
```

**Example:**

![6-3.png](./img/6-3.png)

```solidity
// 方法3:构造函数式
function initStudent3() external {
student = Student(3, 90);
}
// 方法3:构造函数式
function initStudent3() external {
student = Student(3, 90);
}
```

**Example:**

![6-4.png](./img/6-4.png)

```solidity
// 方法4:key value
function initStudent4() external {
student = Student({id: 4, score: 60});
}
// 方法4:key value
function initStudent4() external {
student = Student({id: 4, score: 60});
}
```

**Example:**

![6-5.png](./img/6-5.png)

## 总结
这一讲,我们介绍了solidity中数组(`array`)和结构体(`struct`)的基本用法。下一讲我们将介绍solidity中的哈希表——映射(`mapping`)。

这一讲,我们介绍了Solidity中数组(`array`)和结构体(`struct`)的基本用法。下一讲我们将介绍Solidity中的哈希表——映射(`mapping`)。