以太坊solidity学习记录(六)内存与结构体

个人目录

以太坊solidity学习记录(一)新版在线remix编译器的使用(2020.4.27)
以太坊solidity学习记录(二)基础操作整理
以太坊solidity学习记录(三)基础数据操作
以太坊solidity学习记录(四)地址与交易
以太坊solidity学习记录(五)函数入门
以太坊solidity学习记录(六)内存与结构体

1.memory与storage

结论:
1.在solidity合约内部
函数外部声明的变量默认储存在storage里
函数内部声明的变量默认储存在memory里

storage memory
储存的变量 函数外部声明的变量,即状态变量 函数内部声明的变量,即局部变量
存储的位置 区块链上,永久存在 内存中,运行完之后销毁
运行的位置 区块链网络上 单个节点
传递属性 指针传递 值传递

可参考
Solidity的数据位置特性深入详解(九)| 入门系列(老是遇到转换问题的来看看)
『0007』- Solidity状态变量、局部变量与memory 、storage之间的爱恨情仇

2.结构体基础

直接看代码吧

pragma solidity ^0.4.0;
contract structtest1{
    
    struct stu{
        uint id;
        string name;
        mapping(uint=>string) maptest; //mapping即使在结构体内,初始化时也是可以忽略的
    }
    
    function init1() public returns(uint,string){
        stu memory student1= stu(1234,'stu1');
        return (student1.id,student1.name); //初始化方法一
    }
    
    function init2() public returns(uint,string){
        stu memory student2=stu({name:'stu2',id:5678});
        return (student2.id,student2.name); //初始化方法二
    }
    
    stu tempstudent1; //只要是函数外面的都是storage
    
    function mappingtest() public returns(uint,string){
        stu memory student3=stu({name:'stu3',id:5678});
        //student3.maptest[100]='mapstu3';
       //直接赋值会报错,因为storage不能转化为memory
       tempstudent1=student3;
       //此时tempstudent1,student3使用的是统一指针,所以下面对tempstudent1修改就等于修改student3
       tempstudent1.maptest[100]='how to map';
       return (student3.id,tempstudent1.maptest[100]);
    }
}

运行结果
init1()
在这里插入图片描述
init2()
在这里插入图片描述
mappingtest()
在这里插入图片描述

3.结构体storage转storage

结论
1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal
2.storage可以接受storage的值,并且storage的改动影响其它storage
代码

contract STS{   //此例temp,student1均为storage
    struct stu{
        uint id;
        string name;
    }
    stu student1;
    function structtest(stu storage temp) internal{ //传入storage结构体
        student1=temp; //赋值
        temp.id=2;    //即使只是修改并未再次赋值,student1的id也会改变
    }
    
    function tets() public view returns(uint){
        structtest(student1); 
        return (student1.id);
    }
    
}

运行结果
以太坊solidity学习记录(六)内存与结构体_第1张图片

4.结构体memory转storage

结论:
1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal
2.storage可以接受memory的值
3.memory的改动不影响storage
4.storage的改动不影响memory
代码

contract MTS{
    
    struct stu{
        uint id;
        string name;
    }
    
    stu student1;
    uint memorynum; //记录memory的值是否受storage影响
    function structtest1(stu memory temp) internal{
        student1=temp; //storage可以接受memory的值,但是memory的改动不影响storage
        temp.id=2; //改变memory的值,看看storage值是否随之改变
        memorynum=temp.id;  //如果student1随着temp改变,那么说明storage受memory影响
    }
    
    function structtest2(stu memory temp) internal{
        student1=temp;
        student1.id=3;//改变storage的值,看看memory值是否随之改变
        memorynum=temp.id; //如果temp随着student1改变,那么说明memory受storage影响
    }
    
    function test1() public returns(uint,uint){
        stu memory temp=stu(1,'a');
        structtest1(temp);
        return (student1.id,memorynum);
    }
    
    function test2() public returns(uint,uint){
        stu memory temp=stu(1,'a');
        structtest2(temp);
        return (student1.id,memorynum);
    }
    
}

运行结果
以太坊solidity学习记录(六)内存与结构体_第2张图片

5.结构体storage转memory

结论:
1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal
2.storage可以接受memory的值
3.memory的改动不影响storage
4.storage的改动不影响memory
代码

contract STM{
    
    struct stu{
        uint id;
        string name;
    }
    
    stu student1=stu(1,'a');
    uint memorynum; //记录memory的值是否受storage影响
    function structtest1(stu storage temp) internal{
        stu memory student2=temp;
        student2.id=2;//改变memory的值,看看storage值是否随之改变
        memorynum=student2.id;
    }
    
    function structtest2(stu storage temp) internal{
        stu memory student2=temp;
        temp.id=3;//改变storage的值,看看memory值是否随之改变
        memorynum=student2.id;
    }
    
    function test1() public view returns(uint,uint){
        structtest1(student1);
        return (student1.id,memorynum);
    }
    
    function test2() public view returns(uint,uint){
        structtest2(student1);
        return (student1.id,memorynum);
    }
    
}

运行结果
以太坊solidity学习记录(六)内存与结构体_第3张图片

6.结构体memory转memory

结论
1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal
2.在此处中看似不影响,但是solidity自我优化是的传入的memory转化为指针,然后连锁导致后面的也全部变为指针,相当于storage转storage了
代码

contract MTM{
    
   struct stu{
        uint id;
        string name;
    }
    
    function structtest(stu memory temp) internal{
        stu memory student2;
        student2=temp;
        student2.id=2;
    }
    
    function tets() public view returns(uint){
        stu memory student1=stu(1,'a');
        structtest(student1);
        return (student1.id);
    }
}

运行结果
以太坊solidity学习记录(六)内存与结构体_第4张图片

7.枚举

结论:
1.enum不能为空,不能存在中文
2.作用:提高可读性
代码:

contract enumtest{
    enum enuma{ac,bc,cc,dc} //不需要分号
    function testenumvalue() public view returns(enuma,enuma,enuma,enuma){//虽然return的是数字,但是并不能写uint
        return (enuma.ac,enuma.bc,enuma.cc,enuma.dc);//必须前面加名字.
    }
    
}

运行结果
以太坊solidity学习记录(六)内存与结构体_第5张图片

你可能感兴趣的:(solidity)