Solidity 从入门到实战(六)

本文详细介绍了Solidity中memory和storage的区别,以及结构体的使用,包括内存地址图、枚举等。通过实例展示了如何在函数中传递和操作存储在区块链上的状态变量,以及在内存中的局部变量。强调了memory和storage的独立性,以及它们之间的转换规则。同时,还探讨了结构体中的mapping特性和枚举的定义与使用方法。
摘要由CSDN通过智能技术生成

Solidity 从入门到实战(六)

注意:本专栏主要来自于https://www.bilibili.com/video/BV1St411a7Pk?p=11&spm_id_from=pageDriver的学习笔记以及https://blog.csdn.net/weixin_45067603/article/details/105751748

memory(内存存储)与storage(区块链存储)

具体的区别可访问:『0007』- Solidity状态变量、局部变量与memory 、storage之间的爱恨情仇

在这里插入图片描述

pragma solidity ^0.4.0;

contract memoryTest{
    uint[] arrx; //这个状态变量存储在区块链的网络之上
    //当我们调用此函数的时候,会创建一个可变数组,会在内存中为它分配空间
    function test(uint[] arry) returns(uint){
        
        arrx =arry;//将内存的arry拷贝给区块链的arrx变量
        
        //当我们在函数内部定义了一个可变长度的数组时,实际上,它默认的类型是storage类型,它指向了区块链的arrx,所以当我修改z的元素的时候,我实际上在操作区块链上的arrx
    
        uint []storage z =arrx;
        //通过指针实际上修改了区块链上arrx的长度,说明z和arrx是一样的,操作z的时候,会改变arrx的值
        z[0] =100;
        
        z.length =100;
    }
    //返回arrx第一个元素
    function test2() returns(uint){
        
        return arrx[0];
    }
    //返回arrx的长度
    function test3() returns(uint){
        
        return arrx.length;
    }
}

在这里插入图片描述

结构体

案例1

简单使用结构体

pragma solidity ^0.4.0;


contract structTest{
   //定义结构体 
    struct student{
        
        uint grade;
        string name;
    }
    
    struct student2{
        
        uint grade;
        string name;
        //student stu; 结构体内部不能包含自己本身,但是可以是动态长度的数组,也可以是映射
        student2[] stu; 
        
        mapping(uint =>student2) test;
    }
    //结构体初始化
    function init()view returns(uint,string){
        student memory s = student(100,"吴彦祖");
        return(s.grade,s.name);
    }
    //结构体初始化第二种方式
     function init2()view returns(uint,string){
        student memory s = student({grade:100,name:"吴彦祖"});
        return(s.grade,s.name);
    }
}

在这里插入图片描述

案例2

结构体中的mapping特性

pragma solidity ^0.4.0;

contract structTest{
    
    struct student{
        
        uint grade;
        string name;
        mapping(uint =>string) map;
    }
    
    student wyz;//默认为storage类型,只能够用storage类型来操作结构体中的mapping类型
    //memory的对象不能够直接操作struct结构体中的mapping
   function init() view returns(uint,string,string){
   //在初始化结构体的时候,忽略掉mapping类型
       student memory s = student(100,"吴彦祖");
       //将内存中的s对象赋值给wyz这样的storage对象
       wyz =s;
       //我们只能通过storage对象来操作mapping属性
       wyz.map[0] ="helloworld";
       
       return(s.grade,s.name,wyz.map[0]);
   }
}

在这里插入图片描述

案例3 (memory转storage)

总结

  1. storage可以接受memory的值
  2. memory的改动不影响storage
  3. storage的改动不影响memory
pragma solidity ^0.4.0;

contract structTest{
    
    struct student{
        
        uint grade;
        string name;
    }
    
    student stu;
    //函数的形参传递了指针引用
    //要是函数以结构体作为参数,那么函数修饰符必须有private/internal
    function test(student memory s)internal{
        //将s的值赋给了区块链上的stu
        stu =s;
        //修改函数形参s,只是修改内存中的空间,没有修改掉区块链上的空间,因为它们两个是完全独立的空间
        s.name="吴彦祖";
    }
    
    function test2(student memory s1)internal{
        stu =s1;
        //修改区块链中的值
        stu.name ="胡歌";
    }
  function call() returns(string){
      //tmp在内存中开辟空间,指向student
      student memory tmp = student(100,"tmp");
      
      test(tmp);
      return stu.name;
  }
  function call2() returns(string){
      
      student memory tmp = student(100,"tmp");
      
      test2(tmp);
      return tmp.name; //但是该值没有发生变化
  }
}

内存地址图

在这里插入图片描述

在这里插入图片描述

案例4(storage转memory)

总结

  1. storage可以接受memory的值
  2. memory的改动不影响storage
  3. storage的改动不影响memory
pragma solidity ^0.4.0;

contract structTest{
    
    struct student{
        uint grade;
        string name;
    }
    //定义结构体,并初始化
    student stu=student(100,"赵丽颖");
    //storage类型作为函数的参数
    function test(student storage s)internal view returns(string){
        
        student memory lina = s;
        
        lina.name="吴彦祖"; //改变内存中姓名,观察区块链中的姓名是否改变
        return s.name;
    }
    
    function test2(student storage s1)internal view returns(string){
        student memory liming  =s1;
        s1.name ="胡歌"; //改变区块链中的姓名,观察内存中的姓名是否改变
        return liming.name;
    }
  function call() view returns(string) {
      return test(stu); //没改变
  }
  function call2() view returns(string){
      
      return test2(stu); //没改变
    
  }
}

在这里插入图片描述

案例5(memory转memory)

pragma solidity ^0.4.0;


contract structTest{
    
    struct student{
        uint grade;
        string name;
    }
    
    student stu=student(100,"赵丽颖");
    //memory类型之间的转换,由于solidity的优化,是通过指针来传递的
    function test(student memory s)internal view returns(string){
        
        student memory lina = s;
        
        lina.name="吴彦祖";//都是在内存中,由于lina指向s,修改lina的name属性,相当于修改s的name属性
        return s.name; 
    }
    
    function test2(student memory s1)internal view returns(string){
        student memory liming  =s1;
        s1.name ="胡歌";//都是在内存中,由于liming指向s1,修改liming的name属性,相当于修改s1的name属性
        return liming.name;
    }
  function call() view returns(string) {
      return test(stu);//吴彦祖
  }
  function call2() view returns(string){
      
      return test2(stu);//胡歌
    
  }
}

在这里插入图片描述

案例6(storage转storage)

pragma solidity ^0.4.0;


contract structTest{
    
    struct student{
        uint grade;
        string name;
    }
    
    student stu=student(100,"赵丽颖");
    
    function test(student storage s)internal view returns(string){
        
        student storage lina = s;
        
        lina.name="吴彦祖";
        return s.name;
    }
    
    function test2(student storage s1)internal view returns(string){
        student storage liming  =s1;
        s1.name ="胡歌";
        return liming.name;
    }
  function call() view returns(string) {
      return test(stu);
  }
  function call2() view returns(string){
      
      return test2(stu);
    
  }
}

在这里插入图片描述

枚举

格式:enum 变量名{x,y,z} 没有分号

pragma solidity ^0.4.0;


contract enumTest{
    
   enum men{xiaoming,xiaowang,xiaozhang}
   
    men  studyMen = men.xiaoming;
   
  function getEnum()public pure returns(men){ 
      
      return men.xiaozhang;
  }
  
  function oneDayStudy()public payable  returns(string){//按照视频中所写的,会出现错误,用此种方式不出错
      
      require(studyMen == men.xiaoming);
      studyMen = men.xiaowang;
      return "oneDayStudy with xiaoming";

  }
  
  function twoDayStudy()public view returns(string){
      
     require(studyMen == men.xiaowang);
     return ("twoDayStudy with xiaowang");
  }
}

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟逆袭之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值