Skip to content

Latest commit

 

History

History
104 lines (94 loc) · 5.12 KB

File metadata and controls

104 lines (94 loc) · 5.12 KB

第六课 数组和结构体

本课介绍了数组和结构体的定义和用法

数组

数组可以在声明时指定长度,也可以动态调整大小。 一个元素类型为 T,固定长度为 k 的数组可以声明为 T[k], 而动态数组声明为 T[]。

  • 特点:
    • 访问一个超过它的末端的数组会导致一个失败的断言。方法 .push() 和 .push(value) 可以用来在动态大小的数组末端追加一个新的元素, 其中 .push() 追加一个零初始化的元素并返回它的引用。
    • bytes 和 string 类型的变量是特殊的数组。但不允许用长度或索引来访问。
    • 不可能调整内存数组的大小,必须事先计算出所需的大小,或者创建一个新的内存数组并复制每个元素。
    • 要在外部(而不是公开)函数中使用数组的数组, 需要激活ABI coder v2。
  • 数组成员
    • length: 数组有一个包含元素数量的length成员,memory数组的长度在创建后是固定的。
    • push(): 动态数组拥有push()成员,可以在数组最后添加一个0元素,并返回该元素的引用。
    • push(x): 动态数组拥有push(x)成员,可以在数组最后添加一个x元素。
    • pop(): 动态数组拥有pop()成员,可以移除数组最后一个元素。

结构体

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

  1. 在函数中创建一个storage的struct引用
   function initStudent1() external{
      Student storage _student = student; // assign a copy of student
      _student.id = 11;
      _student.score = 100;
}
  1. 直接引用状态变量的struct
   function initStudent2() external{
      student.id = 1;
      student.score = 80;
   }
  1. 构造函数赋值
   function initStudent3() external {
      student = Student(3, 90);
   }
  1. key-value赋值
   function initStudent4() external {
      student = Student({id: 4, score: 60});
   }

注意:结构体不可能包含其自身类型的成员,尽管结构本身可以是映射成员的值类型, 或者可以包含其本身类型的动态大小的数组。

第7课 映射类型 mapping

Solidity中存储键值对的数据结构,可以理解为哈希表。 声明映射的格式为mapping(_KeyType => _ValueType),其中_KeyType和_ValueType分别是Key和Value的变量类型。

mapping规则

  • 映射的_KeyType只能选择Solidity内置的值类型,不能用自定义的结构体。
  • 不能用于public函数的参数或返回结果中,因为mapping记录的是一种关系 (key - value pair)。
  • 如果映射声明为public,那么Solidity会自动给你创建一个getter函数,可以通过Key来查询对应的Value。
  • 给映射新增的键值对的语法为_Var[_Key] = _Value,其中_Var是映射变量名,_Key和_Value对应新增的键值对。
   function writeMap (uint _Key, address _Value) public{
      idToAddress[_Key] = _Value;
   }

mapping特点

  • 映射不储存任何键(Key)的资讯,也没有length。
  • 映射使用keccak256(abi.encode(key, slot))当成offset存取value,其中slot是映射变量定义所在的插槽位置。
  • 因为Ethereum会定义所有未使用的空间为0,所以未赋值(Value)的键(Key)初始值都是各个type的默认值,如uint的默认值是0。

第8课 变量初始值

在Solidity中,声明但没赋值的变量都有它的初始值或默认值。

值类型初始化变量:

  • boolean: false
  • string: ""
  • int: 0
  • uint: 0
  • enum: 枚举中的第一个元素的值
  • address: 0x0000000000000000000000000000000000000000 (或 address(0))
  • function
    • internal: 空白函数
    • external: 空白函数

引用类型初始化变量:

  • 映射mapping: 所有元素都为其默认值的mapping
  • 结构体struct: 所有成员设为其默认值的结构体
  • 数组array
    • 动态数组: []
    • 静态数组(定长): 所有成员设为其默认值的静态数组

delete

delete会把一个变量的值设置为初始值

   bool public _bool2 = true; 
   function d() external {
      delete _bool2; // delete 会让_bool2变为默认值,false
   } 

第9课 常数 constant和immutable

我们介绍Solidity中和常量相关的两个关键字,constant(常量)和immutable(不变量)。状态变量声明这两个关键字之后,不能在初始化后更改数值。这样做的好处是提升合约的安全性并节省gas。

注意: 只有数值变量可以声明constant和immutable;string和bytes可以声明为constant,但不能为immutable。

  • constant变量必须在声明的时候初始化。
  • immutable变量可以在声明时或构造函数中初始化若,immutable变量既在声明时初始化,又在constructor中初始化,会使用constructor初始化的值。