【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)
中的age
和name
,还有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
引用类型的变量有两种类型,分别是memory
和storage
。
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)
函数时,相当于同时有_name
,name
,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,一切准备就绪,开始我们的学习之旅吧,如果有问题,可以到这里提问。