【2022 元宇宙基础NFT之Solidity OOP编程第09篇】3分钟了解Solidity状态变量、局部变量与memory 、storage之间的简单使用

在上一节中,我们了解了Solidity类型中哪些是值类型,哪些是引用类型,以及值类型引用类型的简单对比。

本篇教程中,我们将全面讲解memory,storage在Solidity开发中的作用,以及值类型引用类型在合约中memory/storage关键字的区别。

一、一段代码清楚认识状态变量、局部变量

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Person {

    int public _age;
    string public _name;

    constructor(int age,string memory name) {
          _age = age;
          _name = name;
    }

    function f(string memory name) pure public {
          string memory name1 = name;
    }
}

在这段代码中,_age_name就属于状态变量constructor(int age,string memory name) 中的agename,还有f(string memory name)中的name以及f()函数中声明的name1都默认属于本地/局部变量

二、值类型代码演示

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Person {

    int public _age;

    constructor(int age) {
      _age = age;
    }

    function f() view public {
      modifyAge(_age);
    }

    function modifyAge(int age) pure internal {
      age = 100;
    }
}

部署合约时,我给构造函数传的值为109,合约部署完毕,通过_age()函数查看状态变量_age的值为109,我试图想通过f()函数调用modifyAge(int age) pure internal 函数来修改_age的值,结果再查看_age的值时,还仍然是109,原因是因为int类型属于值类型,当f()函数里面调用modifyAge(int age) pure internal函数时,虽然传的值是 _age,但实际上是重新创建了一个局部变量age,在修改之前,age的值和_age的值一样,都是109,当age被修改后,只是局部变量age的值发生变化,而_age保持不变。

三、引用类型memory/storage

引用类型的变量有两种类型,分别是memorystorage

3.1 memory(值传递)

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Person {

    string public  _name;

    constructor () {
        _name = "liyuechun";
    }

    function f() view public {

        modifyName(_name);
    }

    function modifyName(string memory name)  pure internal  {

        string memory name1 = name;
        bytes(name1)[0] = 'L';
    }
}

在本案例中,当创建合约时,_name的值为liyuechun,当我们调用f()函数时,f()函数中会将_name的值赋给临时的memory变量name,换句话说,因为name的类型为memory,所以name_name会分别指向不同的对象,当我们尝试去修改name指针指向的值时,_name所指向的内容不会发生变化。

3.2 storage(指针传递)

当函数参数为memory类型时,相当于值传递,而storage类型的函数参数将是指针传递。

如果想要在modifyName函数中通过传递过来的指针修改_name的值,那么必须将函数参数的类型显示设置为storage类型,storage类型拷贝的不是值,而是_name指针,当调用modifyName(_name)函数时,相当于同时有_namename,name1三个指针同时指向同一个对象,我们可以通过三个指针中的任何一个指针修改他们共同指向的内容的值。

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Person {

    string public  _name;

    constructor() {
        _name = "liyuechun";
    }

    function f() public {

        modifyName(_name);
    }

    function modifyName(string storage name)  internal {

        string storage name1 = name;
        bytes(name1)[0] = 'L';
    }
}

部署完合约,我们第一次查看_name变量的值时,值为liyuechun,当我们点击f()函数传入_name进行修改后,_name的值为Liyuechun,原因是因为storage类型属于引用(指针)传递。

⚠️:ok,一切准备就绪,开始我们的学习之旅吧,如果有问题,可以到这里提问

已有 0 用户参与0
0 : 0
+1已打分
电子邮箱
  • 程序咖巴士
联系我们
  • 扫一扫,联系我们