博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
solidity 复杂类型的Data_Location
阅读量:7119 次
发布时间:2019-06-28

本文共 3003 字,大约阅读时间需要 10 分钟。

hot3.png

简介

对于复杂类型例如array,struct都有一个都有一个额外的注解(annotation),可能是storage,memory,calldata之一。根据上下文总是有一个默认的注解类型。但是一般可以通过storage和memory关键字显示的修改。

对于函数的出参和入参一般默认的是memory类型(external 函数的入参例外是强制的calldata类型)

对于局部变量默认的是storage类型(可以通过memory修改)

对于状态变量强制的是storage类型(不能通过memory修改)

关于Data Location

storage

会写入区块链中

memory

不会持久化(不会写入到区块链中)

calldata

不可修改,不可持久化

关于局部变量和状态变量

pragma solidity ^0.4.18;contract DL{    uint [] stateVariable;//状态变量(state variable)    function normal(uint [] inArg) public returns(uint outArg){        uint [] localVar;//局部变量(本地变量,local variable)        return 0;    }    function cd(uint [] inArg)  external returns(uint outArg){        return 0;    }}

上面代码的stateVariable就是状态变量,inArg就是入参,outArg就是出参

stateVariable的data location就是storage

localVar是局部变量,data location是memory

函数normal的inArg的data location是memory outArg也是memory

函数cd的inArg的data location是calldata outArg是memory

总结

强制的 data location:

  1. external 函数的入参: calldata
  2. 状态变量:storage

默认的 data location:

  1. 一般函数的入参和出参(返回参数):memory
  2. 所有局部变量:storage

storage与memory之间的赋值

  1. public的函数的入参的data location不能是storage
function storaegPara(Person storage allen) public returns(uint8 age,string name){    person = allen;    return (person.age,person.name);}

像上面这种就会出编译错误。

  1. 局部变量的memory不能赋值给局部变量的storage,但是可以赋值给状态变量的storage
pragma solidity ^0.4.18;contract DL{    struct Person{        uint8 age;        string name;    }    Person person = Person({age:20,name:"tim"});//状态变量,强制storage(state variable)    function storaegPara(Person storage allen) internal returns(uint8 age,string name){        person = allen;        return (person.age,person.name);    }    function testStoraegPara() returns(uint8 age,string name){        Person allen = Person({age:22,name:"allen"});        return storaegPara(allen);    }}

像上面的就会编译错误。从前面我们知道:

Person allen = Person({age:22,name:"allen"});

等价于:

Person memory allen = Person({age:22,name:"allen"});

当调用storaegPara(allen)的时候,相当于把一个memory的局部allen变量赋值给一个storage的局部变量allen。

这是因为storage是静态分配存储空间的,对于storage的赋值,更像是对指针的赋值。

pragma solidity ^0.4.18;contract DL{    struct Person{        uint8 age;        string name;    }    Person person = Person({age:20,name:"tim"});//状态变量,强制storage(state variable)    function storaegPara(Person memory allen) internal returns(uint8 age,string name){        person = allen;        return (person.age,person.name);    }    function testStoraegPara() returns(uint8 age,string name){        Person memory allen = Person({age:22,name:"allen"});        return storaegPara(allen);    }}
  1. storage可以对memory进行赋值,执行的是拷贝操作。(修改新的memory变量不会影响原来storage变量)

  2. memory对memory的赋值是引用

memory和storage赋值总结

  1. 同类赋值(memory对memory,storage对storage)是引用,相当于指针不会执行数据拷贝。

  2. memory和storage相互赋值,执行的是数据拷贝,但是注意***memory不能对局部storage赋值***

memory和storage 数组

  1. 对于变长数组必须使用new初始化之后才能访问

  2. new 产生的是memory类型的,不能转换为局部的storage,所以可以看到在函数中下面的代码是会出编译错误的:

uint [] storage data = new uint[](1);
  1. 对于storage的变长数组,可以通过给length赋值调整数组长度。还可以使用后面提到的push()方法,来隐式的调整数组长度

  2. 对于memory的变长数组,不支持修改length属性,来调整数组大小。memory的变长数组虽然可以通过参数灵活指定大小,但一旦创建,大小不可调整

转载于:https://my.oschina.net/u/2474629/blog/1841905

你可能感兴趣的文章
RabbitMQ入门-Topic模式
查看>>
多线程面试体系列(13):多线程同步内功心法——PV操作下
查看>>
Work
查看>>
[开源]快速构建文件下载,支持文件加密,自定义限速
查看>>
Mac系统搭建java开发环境
查看>>
菜鸟对新技术的一点看法
查看>>
2016年2月23日----Javascript全局变量和局部变量
查看>>
iOS开发基础知识-多线程概念深入浅出
查看>>
论PHP框架设计模式及MVC的缺陷
查看>>
立flag(java)
查看>>
7-38 数列求和-加强版(20 分)
查看>>
python----字典
查看>>
开发环境eclipse for Mac 下的常用快捷键汇总(基本参照Win系,将Ctrl换为Command)
查看>>
tree与GridView交互
查看>>
zz 鸡汤穷三代,励志毁一生
查看>>
小学期实践心得(2)
查看>>
c#获取电脑硬件信息参数说明(CPU篇 Win32_Processor)
查看>>
oracle报错注入的一些函数
查看>>
Android下载图片/调用系统相机拍照、显示并保存到本地
查看>>
LeetCode算法题-Detect Capital(Java实现)
查看>>