《道德经》第四十二章“万物负阴而抱阳,冲气以为和”。朴素地阐述了宇宙的发生,即为阴阳相和。这两种状态同为一体而又相互转换。易有太极,是生两仪。两仪生四项,四项生八卦。正如storage与memory一样,可以产生四种相关关系。而这四种关系又有各自的区别,但都阐述着同一个问题,那就是传递类型。

实验目的

1. 掌握结构体memory与storage类型转换;理解各部分是什么传递类型及前后的变与不变。

实验要求

1、请准备好纸和笔。先依次查看前面四个示例,用笔画出声明了的storage与memory内存地址,根据代码逻辑列出其中结构体状态变化。

2、思考每个示例中函数futest的返回值是什么?然后编译部署检查结果,思考该函数是什么传递?

以下是本次实验所使用到的测试代码,请使用remix编辑器完成该实验

// 示例1 【storage 转 storage】
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract structtest{
    struct student{
        uint age;
        string name;
    }
    student stu;  //默认storage类型
 
    // storage stu到 storage s的传递,不是副本,是指向 (s是指针,指向stu),
    function test(student storage s) internal {  
        student storage guy = s;
        guy.name = "chen";
    }    
    //返回值在命令窗口展看 output查看  输出 chen (发生改变)
    function  futest() public returns (string memory) {
        test(stu);
        return stu.name;
    }
}
// 示例2 【memory转 storage】
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract structtest{
    struct  student{
        uint age;
        string  name;
    }
    student stu;  //storage
 
    function test(student memory s) internal {   
        //memory s 传递给 storage stu, 修改s 的成员,对于stu 不产生影响
        stu = s;
        s.name = "chen";
        //如果修改后 再进行传递,对于修改后的s 传递过去,就会改变stu 
        // stu = s;
    }
    // 显示的是 zhang参数, s的修改不起作用
    function  futest() public returns (string memory) {  
        student memory tmp = student(10,"zhang");
        test(tmp);
        return stu.name;
    }
}
// 示例3 【storage转 memory】
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
 
contract structtest{
    struct  student{
        uint age;
        string  name;
    }
    student stu = student(100,"zhang");  
 
    // 内存memory不能改变全局变量storage
    //storage s 形参 是一个指针,引用传递 
    function test(student storage s) pure internal {  
        //storage到 memory, 是叫拷贝,s 拷贝到 guy 内存中的一个副本
        student memory guy = s;  
        guy.name = "chen";
    }
    
    // 还是stu,修改memory 不改变storage 
    function  futest() public view returns (string memory) {
        test(stu);
        return stu.name;
    }
}
// 示例4 【memory转 memory】
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
 
contract structtest{
    struct  student{
        uint age;
        string  name;
    }
    
//memory转memory 是 指针传递, s 赋值给 lina, lina 指向 s
    function test(student memory s) pure internal {   
        student memory lina = s;
        //对lina修改 等于 修改 s 等于修改 guy
        lina.name = "zhang";
    }
    function  futest() public pure returns (string memory) {
        student memory guy =  student(100,"chen");
        test(guy);
        return guy.name;
    }
}
//示例5
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; 
 
contract StructTest{ 
    // 定义一个结构体 
    struct Student{ 
        string name; 
        uint grade; 
       mapping(uint=>string) map;
}
//mapping(uint => Student)students;
//    struct teacher{
//        string name;
//        uint age;
//    }
//uint public studentID;
    Student stu; //可删除
    function init() public returns(string memory,uint, string memory){
        Student memory s = Student("tong",100); 
        stu.map[0] = "jack";
        return(s.name,s.grade, stu.map[0]); 
}
//function init2(string  _name,uint _grade) public returns(uint){
//        studentID ++;
         //按要求补充代码
//        return(studentID); 
//    }
//function getInformation(uint studentID)public view returns(string memory,uint,string memory){
  //      Student storage s = students[studentID]; 
   //     return (s.name,s.grade,s.map[studentID].name);
    //}
}

下面是本次实验所配套的视频教程: