存储位置
基础
默认数据位置
状态变量默认storage
内部函数参数默认memory
外部函数参数默认calldata例如
pragma solidity ^0.8.0;
contract SimpleAssign{
// storage 类型
struct S{
string a;
uint b;
}
function assign(S s) internal{
// 函数参数默认是 memory 类型,即 s 是 memory 类型
// 局部变量默认 storage 类型
// 将一个memory类型的参数赋值给storage类型的局部变量会报错。
S tmp = s; // 报错
}
}值转换
storage–>storage
把一个storage类型赋值给一个 storage 类型时,只是修改其指针(引用传递)。
memory–>storage
分为 2 种情况: a. 将 memory–>状态变量; 即将内存中的变量拷贝到存储中(值传递)
b.将memeory–>局部变量 报错
storage–>memory
即将数据从storage拷贝到memory中
memory–>memory
和storage转storage一样是引用传递
Memory
概述
存储在内存中,即分配、即使用,越过作用域则不可访问,等待被回收。 内存是易失性读写字节可寻址空间。它主要用于在执行过程中存储数据,主要用于向内部函数传递参数。鉴于这是易失性区域,每个消息调用都以清除内存开始。所有位置最初都定义为零。作为calldata,内存可以按字节级别寻址,但一次只能读取32字节的字。 当我们写入以前未使用过的单词时,内存被称为“扩展”。除了写入本身的成本之外,这种扩展也有成本,前 724 字节呈线性增长,之后呈二次方增长。
特点
操作码
EVM 提供了三个操作码来与内存区域进行交互
Calldata
概述
存储函数参数,它是只读的,不会永久存储的一个数据位置。外部函数的参数被强制指定为 calldata,效果与 memory 类似。
特点
操作码
EVM 提供的用于操作调用数据的操作码
常用操作
Memory变量
Memory变量临时变量(内存型),合约函数执行完成时,内存型变量被移除。 在函数参数或返回值声明时,如果返回数据的类型是变长的,那么需要加memory修饰,例如
等类型都需要使用memory。
storage变量
storage的作用类似于C++中的引用传递,用storage修饰的变量等同于右值的一个分身,对其进行修改也会影响到本尊。
区别
如果数组中的结构体赋值给函数中声明的变量,使用memory修饰获得的是一个副本,也就是拷贝
如果使用storage修饰变量,那么得到的是一个引用,就是p 是指向 persons[_id] 的指针。例如
Last updated