前言
写本文的目的是记录自己对于区块链技术的学习,方便日后查漏补缺,solidity是一门智能合约语言,是静态类型语言,支持继承等特性。solidity中不存在 undefine和null的概念,每个新声明的变量都会根据其类型赋予默认值。引用类型包括结构,数组和映射。
一、数据位置
如果使用引用类型,则必须明确指明数据存储哪种类型的位置空间里 :
- memory 即数据在内存中,因此数据仅在其生命周期内(函数调用期间)有效。
- calldata 用来保存函数参数的特殊数据位置,是一个只读位置,不可修改的、非持久的函数参数存储区域,效果大多类似 内存memory .
- storage 状态变量保存的位置,只要合约存在就一直存储
更改数据位置或类型转换将始终产生自动进行一份拷贝,而在同一数据位置内(对于storage来说)的复制仅在某些情况下进行拷贝。
尽量使用calldata作为数据位置,因为它将避免复制,并确保不能修改数据。 函数的返回值中也可以使用calldata数据位置的数组和结构,但是无法给其分配空间。
在0.6.9版本之前,引用类型参数的数据位置有限制,外部函数中使用calldata,公共函数中使用memory,以及内部和私有函数中的memory或storage。 现在memory和calldata在所有函数中都被允许使用,无论其可见性如何。
在版本0.5.0之前,数据位置可以省略,并且根据变量的类型,函数类型等有默认数据位置,但是所有复杂类型现在必须提供明确的数据位置。
数据位置与赋值行为
数据位置不仅仅表示数据如何保存,它同样影响着赋值行为:
- 在storage和memory之间两两赋值(或者从calldata赋值 ),都会创建一份独立的拷贝。
- 从memory到memory的赋值只创建引用, 这意味着更改内存变量,其他引用相同数据的所有其他内存变量的值也会跟着改变。
- 从storage到本地存储变量的赋值也只分配一个引用。
- 其他的向storage的赋值,总是进行拷贝。 这种情况的示例如对状态变量或storage的结构体类型的局部变量成员的赋值,即使局部变量本身是一个引用,也会进行一份拷贝
二、数组
数组可以在声明时指定长度,也可以动态调整大小。
一个元素类型为T
,固定长度为k
的数组可以声明为T[k]
,而动态数组声明为T[]。