Solidity 赋值的数据位置规则
solidity 数据可以通过两种方式从一个变量复制到另一个变量。
一种方法是复制整个数据(按值复制),另一种方法是引用复制。
solidity 从一个位置的变量赋值到另一个位置的变量,遵循一定的默认规则。
1. 规则1 – 状态变量赋值给状态变量
将一个状态变量赋值给另一个状态变量,将创建一个新的副本。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Locations { uint public stateVar1 = 10; uint public stateVar2 = 20; function do() public returns (uint) { stateVar1 = stateVar2; stateVar2 = 30; return stateVar1; //returns 20 } }
本例中,stateVar1 和 stateVar2 是状态变量。
在 do 函数中,我们将 stateVar2 的值赋值给 stateVar1。
stateVar1 的值是 20,但是为了确定它创建了一个新的副本,我们改变了stateVar2 的值。因此,如果它不创建副本,那么 stateVar1 的值应该是30,创建副本则是20。
这同样适用于引用类型的状态变量。
2. 规则2 – 内存局部变量复制到状态变量
从内存局部变量复制到状态变量,总是会创建一个新的副本。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Locations { uint stateVar = 10; //storage function do() public returns(uint) { uint localVar = 20; //memory stateVar = localVar; localVar = 40; return stateVar; //returns 20 } }
在上面的例子中,我们有一个状态变量和一个局部内存变量。在函数中,我们把局部变量的值赋给状态变量。
为了检查赋值后的行为,我们改变了局部变量的值,并返回状态变量的值。
这里可以看到,它会返回20,说明从内存局部变量复制到状态变量,会创建一个新的副本。
3. 规则3 – 状态变量复制到内存局部变量
从状态变量复制到内存局部变量,将创建一个副本。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Locations { uint stateVar = 10; //storage function do() public returns(uint) { uint localVar = 20; //memory localVar = stateVar; stateVar = 40; return localVar; //returns 10 } }
在这里,将状态变量的值赋给了内存局部变量,并改变了状态变量的值。为了检查局部变量的值是否已经更改,返回它的值。
我们部署运行后,调用 do 会返回10,说明从状态变量复制到内存局部变量,将创建一个副本。
4. 规则4 – 内存变量复制到内存变量
对于引用类型的局部变量,从一个内存变量复制到另一个内存变量,不会创建副本。
对于值类型的局部变量,从一个内存变量复制到另一个内存变量,仍然创建一个新副本。
引用类型
// SPDX-License-Identifier: MIT pragma solidity ^ 0.8.0; contract Locations { function doSomething() public pure returns(uint[] memory, uint[] memory) { uint[] memory localMemoryArray1 = new uint[](3); localMemoryArray1[0] = 4; localMemoryArray1[1] = 5; localMemoryArray1[2] = 6; uint[] memory localMemoryArray2 = localMemoryArray1; localMemoryArray1[0] = 10; return (localMemoryArray1, localMemoryArray2); //returns 10,4,6 | 10,4,6 } }
在上面的示例中,我们在内存中初始化了一个名为localMemoryArray1的数组变量,并赋值为4、5和6。然后,我们将该变量复制到名为localMemoryArray2的新内存变量中。
然后,我们修改了localMemoryArray1中第一个索引的值,并返回了两个数组。这将得到相同的结果,因为它们都指向相同的位置。
让我们对值类型进行相同的检查。下面的函数将创建一个新的副本并返回20。
值类型
// SPDX-License-Identifier: MIT pragma solidity ^ 0.8.0; contract Locations { function do() public pure returns(uint) { uint localVar1 = 10; //memory uint localVar2 = 20; //memory localVar1 = localVar2; localVar2 = 40; return localVar1; //returns 20 } }
下一章:Solidity 函数
函数是一组可重用代码的包装,接受输入,返回输出。Solidity 支持函数定义和调用。1. 函数定义Solidity中, 定义函数的语法如下:语法function function_name(<paramete ...